|
|
@@ -25,313 +25,415 @@ |
|
|
|
* |
|
|
|
**************************************************************************/ |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
#include <assert.h> |
|
|
|
#include "imports.h" |
|
|
|
|
|
|
|
#include "i915_reg.h" |
|
|
|
#include "i915_context.h" |
|
|
|
#include "i915_debug.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const char *opcodes[0x20] = { |
|
|
|
"NOP", |
|
|
|
"ADD", |
|
|
|
"MOV", |
|
|
|
"MUL", |
|
|
|
"MAD", |
|
|
|
"DP2ADD", |
|
|
|
"DP3", |
|
|
|
"DP4", |
|
|
|
"FRC", |
|
|
|
"RCP", |
|
|
|
"RSQ", |
|
|
|
"EXP", |
|
|
|
"LOG", |
|
|
|
"CMP", |
|
|
|
"MIN", |
|
|
|
"MAX", |
|
|
|
"FLR", |
|
|
|
"MOD", |
|
|
|
"TRC", |
|
|
|
"SGE", |
|
|
|
"SLT", |
|
|
|
"TEXLD", |
|
|
|
"TEXLDP", |
|
|
|
"TEXLDB", |
|
|
|
"TEXKILL", |
|
|
|
"DCL", |
|
|
|
"0x1a", |
|
|
|
"0x1b", |
|
|
|
"0x1c", |
|
|
|
"0x1d", |
|
|
|
"0x1e", |
|
|
|
"0x1f", |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static const int args[0x20] = { |
|
|
|
0, /* 0 nop */ |
|
|
|
2, /* 1 add */ |
|
|
|
1, /* 2 mov */ |
|
|
|
2, /* 3 m ul */ |
|
|
|
3, /* 4 mad */ |
|
|
|
3, /* 5 dp2add */ |
|
|
|
2, /* 6 dp3 */ |
|
|
|
2, /* 7 dp4 */ |
|
|
|
1, /* 8 frc */ |
|
|
|
1, /* 9 rcp */ |
|
|
|
1, /* a rsq */ |
|
|
|
1, /* b exp */ |
|
|
|
1, /* c log */ |
|
|
|
3, /* d cmp */ |
|
|
|
2, /* e min */ |
|
|
|
2, /* f max */ |
|
|
|
1, /* 10 flr */ |
|
|
|
1, /* 11 mod */ |
|
|
|
1, /* 12 trc */ |
|
|
|
2, /* 13 sge */ |
|
|
|
2, /* 14 slt */ |
|
|
|
1, |
|
|
|
1, |
|
|
|
1, |
|
|
|
1, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static const char *regname[0x8] = { |
|
|
|
"R", |
|
|
|
"T", |
|
|
|
"CONST", |
|
|
|
"S", |
|
|
|
"OC", |
|
|
|
"OD", |
|
|
|
"U", |
|
|
|
"UNKNOWN", |
|
|
|
}; |
|
|
|
|
|
|
|
static void |
|
|
|
print_reg_type_nr(unsigned type, unsigned nr) |
|
|
|
static GLboolean debug( struct debug_stream *stream, const char *name, GLuint len ) |
|
|
|
{ |
|
|
|
switch (type) { |
|
|
|
case REG_TYPE_T: |
|
|
|
switch (nr) { |
|
|
|
case T_DIFFUSE: |
|
|
|
fprintf(stderr, "T_DIFFUSE"); |
|
|
|
return; |
|
|
|
case T_SPECULAR: |
|
|
|
fprintf(stderr, "T_SPECULAR"); |
|
|
|
return; |
|
|
|
case T_FOG_W: |
|
|
|
fprintf(stderr, "T_FOG_W"); |
|
|
|
return; |
|
|
|
default: |
|
|
|
fprintf(stderr, "T_TEX%d", nr); |
|
|
|
return; |
|
|
|
} |
|
|
|
case REG_TYPE_OC: |
|
|
|
if (nr == 0) { |
|
|
|
fprintf(stderr, "oC"); |
|
|
|
return; |
|
|
|
} |
|
|
|
break; |
|
|
|
case REG_TYPE_OD: |
|
|
|
if (nr == 0) { |
|
|
|
fprintf(stderr, "oD"); |
|
|
|
return; |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
GLuint i; |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
|
|
|
|
if (len == 0) { |
|
|
|
_mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); |
|
|
|
assert(0); |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "%s[%d]", regname[type], nr); |
|
|
|
} |
|
|
|
if (stream->print_addresses) |
|
|
|
_mesa_printf("%08x: ", stream->offset); |
|
|
|
|
|
|
|
|
|
|
|
#define REG_SWIZZLE_MASK 0x7777 |
|
|
|
#define REG_NEGATE_MASK 0x8888 |
|
|
|
_mesa_printf("%s (%d dwords):\n", name, len); |
|
|
|
for (i = 0; i < len; i++) |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[i]); |
|
|
|
_mesa_printf("\n"); |
|
|
|
|
|
|
|
#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ |
|
|
|
(SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ |
|
|
|
(SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ |
|
|
|
(SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) |
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
print_reg_neg_swizzle(unsigned reg) |
|
|
|
static const char *get_prim_name( GLuint val ) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
|
|
|
|
if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && |
|
|
|
(reg & REG_NEGATE_MASK) == 0) |
|
|
|
return; |
|
|
|
|
|
|
|
fprintf(stderr, "."); |
|
|
|
|
|
|
|
for (i = 3; i >= 0; i--) { |
|
|
|
if (reg & (1 << ((i * 4) + 3))) |
|
|
|
fprintf(stderr, "-"); |
|
|
|
|
|
|
|
switch ((reg >> (i * 4)) & 0x7) { |
|
|
|
case 0: |
|
|
|
fprintf(stderr, "x"); |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
fprintf(stderr, "y"); |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
fprintf(stderr, "z"); |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
fprintf(stderr, "w"); |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
fprintf(stderr, "0"); |
|
|
|
break; |
|
|
|
case 5: |
|
|
|
fprintf(stderr, "1"); |
|
|
|
break; |
|
|
|
default: |
|
|
|
fprintf(stderr, "?"); |
|
|
|
break; |
|
|
|
} |
|
|
|
switch (val & PRIM3D_MASK) { |
|
|
|
case PRIM3D_TRILIST: return "TRILIST"; break; |
|
|
|
case PRIM3D_TRISTRIP: return "TRISTRIP"; break; |
|
|
|
case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; |
|
|
|
case PRIM3D_TRIFAN: return "TRIFAN"; break; |
|
|
|
case PRIM3D_POLY: return "POLY"; break; |
|
|
|
case PRIM3D_LINELIST: return "LINELIST"; break; |
|
|
|
case PRIM3D_LINESTRIP: return "LINESTRIP"; break; |
|
|
|
case PRIM3D_RECTLIST: return "RECTLIST"; break; |
|
|
|
case PRIM3D_POINTLIST: return "POINTLIST"; break; |
|
|
|
case PRIM3D_DIB: return "DIB"; break; |
|
|
|
case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; |
|
|
|
case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; |
|
|
|
default: return "????"; break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
print_src_reg(unsigned dword) |
|
|
|
static GLboolean debug_prim( struct debug_stream *stream, const char *name, |
|
|
|
GLboolean dump_floats, |
|
|
|
GLuint len ) |
|
|
|
{ |
|
|
|
unsigned nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; |
|
|
|
unsigned type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; |
|
|
|
print_reg_type_nr(type, nr); |
|
|
|
print_reg_neg_swizzle(dword); |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
const char *prim = get_prim_name( ptr[0] ); |
|
|
|
GLuint i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_mesa_printf("%s %s (%d dwords):\n", name, prim, len); |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[0]); |
|
|
|
for (i = 1; i < len; i++) { |
|
|
|
if (dump_floats) |
|
|
|
_mesa_printf("\t\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); |
|
|
|
else |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[i]); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_mesa_printf("\n"); |
|
|
|
|
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
i915_print_ureg(const char *msg, unsigned ureg) |
|
|
|
|
|
|
|
|
|
|
|
static GLboolean debug_program( struct debug_stream *stream, const char *name, GLuint len ) |
|
|
|
{ |
|
|
|
fprintf(stderr, "%s: ", msg); |
|
|
|
print_src_reg(ureg >> 8); |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
|
|
|
|
if (len == 0) { |
|
|
|
_mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); |
|
|
|
assert(0); |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
if (stream->print_addresses) |
|
|
|
_mesa_printf("%08x: ", stream->offset); |
|
|
|
|
|
|
|
_mesa_printf("%s (%d dwords):\n", name, len); |
|
|
|
i915_disassemble_program( ptr, len ); |
|
|
|
|
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
print_dest_reg(unsigned dword) |
|
|
|
|
|
|
|
static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLuint len ) |
|
|
|
{ |
|
|
|
unsigned nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; |
|
|
|
unsigned type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; |
|
|
|
print_reg_type_nr(type, nr); |
|
|
|
if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) |
|
|
|
return; |
|
|
|
fprintf(stderr, "."); |
|
|
|
if (dword & A0_DEST_CHANNEL_X) |
|
|
|
fprintf(stderr, "x"); |
|
|
|
if (dword & A0_DEST_CHANNEL_Y) |
|
|
|
fprintf(stderr, "y"); |
|
|
|
if (dword & A0_DEST_CHANNEL_Z) |
|
|
|
fprintf(stderr, "z"); |
|
|
|
if (dword & A0_DEST_CHANNEL_W) |
|
|
|
fprintf(stderr, "w"); |
|
|
|
} |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
GLuint old_offset = stream->offset + len * sizeof(GLuint); |
|
|
|
GLuint i; |
|
|
|
|
|
|
|
_mesa_printf("%s (%d dwords):\n", name, len); |
|
|
|
for (i = 0; i < len; i++) |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[i]); |
|
|
|
|
|
|
|
stream->offset = ptr[1] & ~0x3; |
|
|
|
|
|
|
|
if (stream->offset < old_offset) |
|
|
|
_mesa_printf("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", |
|
|
|
old_offset, stream->offset ); |
|
|
|
else |
|
|
|
_mesa_printf("\n... skipping from 0x%x --> 0x%x ...\n\n", |
|
|
|
old_offset, stream->offset ); |
|
|
|
|
|
|
|
#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) |
|
|
|
#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) |
|
|
|
#define GET_SRC2_REG(r) (r) |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
print_arith_op(unsigned opcode, const unsigned * program) |
|
|
|
static GLboolean debug_variable_length_prim( struct debug_stream *stream ) |
|
|
|
{ |
|
|
|
if (opcode != A0_NOP) { |
|
|
|
print_dest_reg(program[0]); |
|
|
|
if (program[0] & A0_DEST_SATURATE) |
|
|
|
fprintf(stderr, " = SATURATE "); |
|
|
|
else |
|
|
|
fprintf(stderr, " = "); |
|
|
|
} |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
const char *prim = get_prim_name( ptr[0] ); |
|
|
|
GLuint i, len; |
|
|
|
|
|
|
|
fprintf(stderr, "%s ", opcodes[opcode]); |
|
|
|
GLushort *idx = (GLushort *)(ptr+1); |
|
|
|
for (i = 0; idx[i] != 0xffff; i++) |
|
|
|
; |
|
|
|
|
|
|
|
print_src_reg(GET_SRC0_REG(program[0], program[1])); |
|
|
|
if (args[opcode] == 1) { |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
len = 1+(i+2)/2; |
|
|
|
|
|
|
|
fprintf(stderr, ", "); |
|
|
|
print_src_reg(GET_SRC1_REG(program[1], program[2])); |
|
|
|
if (args[opcode] == 2) { |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
return; |
|
|
|
_mesa_printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); |
|
|
|
for (i = 0; i < len; i++) |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[i]); |
|
|
|
_mesa_printf("\n"); |
|
|
|
|
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static GLboolean debug_load_immediate( struct debug_stream *stream, |
|
|
|
const char *name, |
|
|
|
GLuint len ) |
|
|
|
{ |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
GLuint bits = (ptr[0] >> 4) & 0xff; |
|
|
|
GLuint i, j = 0; |
|
|
|
|
|
|
|
_mesa_printf("%s (%d dwords, flags: %x):\n", name, len, bits); |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[j++]); |
|
|
|
|
|
|
|
for (i = 0; i < 8; i++) { |
|
|
|
if (bits & (1<<i)) { |
|
|
|
_mesa_printf("\t LIS%d: 0x%08x\n", i, ptr[j++]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, ", "); |
|
|
|
print_src_reg(GET_SRC2_REG(program[2])); |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
return; |
|
|
|
_mesa_printf("\n"); |
|
|
|
|
|
|
|
assert(j == len); |
|
|
|
|
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
print_tex_op(unsigned opcode, const unsigned * program) |
|
|
|
static GLboolean debug_load_indirect( struct debug_stream *stream, |
|
|
|
const char *name, |
|
|
|
GLuint len ) |
|
|
|
{ |
|
|
|
print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); |
|
|
|
fprintf(stderr, " = "); |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
GLuint bits = (ptr[0] >> 8) & 0x3f; |
|
|
|
GLuint i, j = 0; |
|
|
|
|
|
|
|
_mesa_printf("%s (%d dwords):\n", name, len); |
|
|
|
_mesa_printf("\t\t0x%08x\n", ptr[j++]); |
|
|
|
|
|
|
|
for (i = 0; i < 6; i++) { |
|
|
|
if (bits & (1<<i)) { |
|
|
|
switch (1<<(8+i)) { |
|
|
|
case LI0_STATE_STATIC_INDIRECT: |
|
|
|
_mesa_printf(" STATIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
_mesa_printf(" 0x%08x\n", ptr[j++]); |
|
|
|
break; |
|
|
|
case LI0_STATE_DYNAMIC_INDIRECT: |
|
|
|
_mesa_printf(" DYNAMIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
break; |
|
|
|
case LI0_STATE_SAMPLER: |
|
|
|
_mesa_printf(" SAMPLER: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
_mesa_printf(" 0x%08x\n", ptr[j++]); |
|
|
|
break; |
|
|
|
case LI0_STATE_MAP: |
|
|
|
_mesa_printf(" MAP: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
_mesa_printf(" 0x%08x\n", ptr[j++]); |
|
|
|
break; |
|
|
|
case LI0_STATE_PROGRAM: |
|
|
|
_mesa_printf(" PROGRAM: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
_mesa_printf(" 0x%08x\n", ptr[j++]); |
|
|
|
break; |
|
|
|
case LI0_STATE_CONSTANTS: |
|
|
|
_mesa_printf(" CONSTANTS: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
|
|
|
_mesa_printf(" 0x%08x\n", ptr[j++]); |
|
|
|
break; |
|
|
|
default: |
|
|
|
assert(0); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "%s ", opcodes[opcode]); |
|
|
|
if (bits == 0) { |
|
|
|
_mesa_printf("\t DUMMY: 0x%08x\n", ptr[j++]); |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); |
|
|
|
_mesa_printf("\n"); |
|
|
|
|
|
|
|
print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & |
|
|
|
REG_TYPE_MASK, |
|
|
|
(program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
|
|
|
|
assert(j == len); |
|
|
|
|
|
|
|
stream->offset += len * sizeof(GLuint); |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
print_dcl_op(unsigned opcode, const unsigned * program) |
|
|
|
static GLboolean i915_debug_packet( struct debug_stream *stream ) |
|
|
|
{ |
|
|
|
fprintf(stderr, "%s ", opcodes[opcode]); |
|
|
|
print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); |
|
|
|
fprintf(stderr, "\n"); |
|
|
|
GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); |
|
|
|
GLuint cmd = *ptr; |
|
|
|
|
|
|
|
switch (((cmd >> 29) & 0x7)) { |
|
|
|
case 0x0: |
|
|
|
switch ((cmd >> 23) & 0x3f) { |
|
|
|
case 0x0: |
|
|
|
return debug(stream, "MI_NOOP", 1); |
|
|
|
case 0x3: |
|
|
|
return debug(stream, "MI_WAIT_FOR_EVENT", 1); |
|
|
|
case 0x4: |
|
|
|
return debug(stream, "MI_FLUSH", 1); |
|
|
|
case 0xA: |
|
|
|
debug(stream, "MI_BATCH_BUFFER_END", 1); |
|
|
|
return GL_FALSE; |
|
|
|
case 0x22: |
|
|
|
return debug(stream, "MI_LOAD_REGISTER_IMM", 3); |
|
|
|
case 0x31: |
|
|
|
return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
break; |
|
|
|
case 0x1: |
|
|
|
break; |
|
|
|
case 0x2: |
|
|
|
switch ((cmd >> 22) & 0xff) { |
|
|
|
case 0x50: |
|
|
|
return debug(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); |
|
|
|
case 0x53: |
|
|
|
return debug(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); |
|
|
|
default: |
|
|
|
return debug(stream, "blit command", (cmd & 0xff) + 2); |
|
|
|
} |
|
|
|
break; |
|
|
|
case 0x3: |
|
|
|
switch ((cmd >> 24) & 0x1f) { |
|
|
|
case 0x6: |
|
|
|
return debug(stream, "3DSTATE_ANTI_ALIASING", 1); |
|
|
|
case 0x7: |
|
|
|
return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); |
|
|
|
case 0x8: |
|
|
|
return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); |
|
|
|
case 0x9: |
|
|
|
return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); |
|
|
|
case 0xb: |
|
|
|
return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); |
|
|
|
case 0xc: |
|
|
|
return debug(stream, "3DSTATE_MODES5", 1); |
|
|
|
case 0xd: |
|
|
|
return debug(stream, "3DSTATE_MODES4", 1); |
|
|
|
case 0x15: |
|
|
|
return debug(stream, "3DSTATE_FOG_COLOR", 1); |
|
|
|
case 0x16: |
|
|
|
return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); |
|
|
|
case 0x1c: |
|
|
|
/* 3DState16NP */ |
|
|
|
switch((cmd >> 19) & 0x1f) { |
|
|
|
case 0x10: |
|
|
|
return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); |
|
|
|
case 0x11: |
|
|
|
return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
break; |
|
|
|
case 0x1d: |
|
|
|
/* 3DStateMW */ |
|
|
|
switch ((cmd >> 16) & 0xff) { |
|
|
|
case 0x0: |
|
|
|
return debug(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); |
|
|
|
case 0x1: |
|
|
|
return debug(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); |
|
|
|
case 0x4: |
|
|
|
return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); |
|
|
|
case 0x5: |
|
|
|
return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); |
|
|
|
case 0x6: |
|
|
|
return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); |
|
|
|
case 0x7: |
|
|
|
return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); |
|
|
|
case 0x80: |
|
|
|
return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); |
|
|
|
case 0x81: |
|
|
|
return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); |
|
|
|
case 0x83: |
|
|
|
return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); |
|
|
|
case 0x85: |
|
|
|
return debug(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); |
|
|
|
case 0x88: |
|
|
|
return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); |
|
|
|
case 0x89: |
|
|
|
return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); |
|
|
|
case 0x8e: |
|
|
|
return debug(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); |
|
|
|
case 0x97: |
|
|
|
return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); |
|
|
|
case 0x98: |
|
|
|
return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); |
|
|
|
case 0x99: |
|
|
|
return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); |
|
|
|
case 0x9a: |
|
|
|
return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); |
|
|
|
case 0x9c: |
|
|
|
return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); |
|
|
|
default: |
|
|
|
assert(0); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
break; |
|
|
|
case 0x1e: |
|
|
|
if (cmd & (1 << 23)) |
|
|
|
return debug(stream, "???", (cmd & 0xffff) + 1); |
|
|
|
else |
|
|
|
return debug(stream, "", 1); |
|
|
|
break; |
|
|
|
case 0x1f: |
|
|
|
if ((cmd & (1 << 23)) == 0) |
|
|
|
return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); |
|
|
|
else if (cmd & (1 << 17)) |
|
|
|
{ |
|
|
|
if ((cmd & 0xffff) == 0) |
|
|
|
return debug_variable_length_prim(stream); |
|
|
|
else |
|
|
|
return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); |
|
|
|
} |
|
|
|
else |
|
|
|
return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); |
|
|
|
break; |
|
|
|
default: |
|
|
|
return debug(stream, "", 0); |
|
|
|
} |
|
|
|
default: |
|
|
|
assert(0); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
assert(0); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
i915_disassemble_program(const unsigned * program, unsigned sz) |
|
|
|
i915_dump_batchbuffer( struct i915_context *i915, |
|
|
|
GLuint *start, |
|
|
|
GLuint *end ) |
|
|
|
{ |
|
|
|
unsigned size = program[0] & 0x1ff; |
|
|
|
unsigned i; |
|
|
|
struct debug_stream stream; |
|
|
|
GLuint bytes = (end - start) * 4; |
|
|
|
GLboolean done = GL_FALSE; |
|
|
|
|
|
|
|
fprintf(stderr, "BEGIN\n"); |
|
|
|
fprintf(stderr, "\n\nBATCH: (%d)\n", bytes / 4); |
|
|
|
|
|
|
|
if (size + 2 != sz) { |
|
|
|
fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, |
|
|
|
size + 2, sz); |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
stream.offset = 0; |
|
|
|
stream.ptr = (char *)start; |
|
|
|
stream.print_addresses = 0; |
|
|
|
|
|
|
|
program++; |
|
|
|
for (i = 1; i < sz; i += 3, program += 3) { |
|
|
|
unsigned opcode = program[0] & (0x1f << 24); |
|
|
|
while (!done && |
|
|
|
stream.offset < bytes && |
|
|
|
stream.offset >= 0) |
|
|
|
{ |
|
|
|
if (!i915_debug_packet( &stream )) |
|
|
|
break; |
|
|
|
|
|
|
|
if ((unsigned) opcode >= A0_NOP && opcode <= A0_SLT) |
|
|
|
print_arith_op(opcode >> 24, program); |
|
|
|
else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) |
|
|
|
print_tex_op(opcode >> 24, program); |
|
|
|
else if (opcode == D0_DCL) |
|
|
|
print_dcl_op(opcode >> 24, program); |
|
|
|
else |
|
|
|
fprintf(stderr, "Unknown opcode 0x%x\n", opcode); |
|
|
|
assert(stream.offset <= bytes && |
|
|
|
stream.offset >= 0); |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "END\n\n"); |
|
|
|
fprintf(stderr, "END-BATCH\n\n\n"); |
|
|
|
} |
|
|
|
|
|
|
|
|