New driver for i915 as well as older i830/i845/i865 chipsets.
[mesa.git] / src / mesa / drivers / dri / i915 / i915_debug.c
1 #include "i915_reg.h"
2 #include "i915_context.h"
3 #include <stdio.h>
4
5
6 static const char *opcodes[0x20] = {
7 "NOP",
8 "ADD",
9 "MOV",
10 "MUL",
11 "MAD",
12 "DP2ADD",
13 "DP3",
14 "DP4",
15 "FRC",
16 "RCP",
17 "RSQ",
18 "EXP",
19 "LOG",
20 "CMP",
21 "MIN",
22 "MAX",
23 "FLR",
24 "MOD",
25 "TRC",
26 "SGE",
27 "SLT",
28 "TEXLD",
29 "TEXLDP",
30 "TEXLDB",
31 "TEXKILL",
32 "DCL",
33 "0x1a",
34 "0x1b",
35 "0x1c",
36 "0x1d",
37 "0x1e",
38 "0x1f",
39 };
40
41
42 static const int args[0x20] = {
43 0, /* 0 nop */
44 2, /* 1 add */
45 1, /* 2 mov */
46 2, /* 3 m ul */
47 3, /* 4 mad */
48 3, /* 5 dp2add */
49 2, /* 6 dp3 */
50 2, /* 7 dp4 */
51 1, /* 8 frc */
52 1, /* 9 rcp */
53 1, /* a rsq */
54 1, /* b exp */
55 1, /* c log */
56 3, /* d cmp */
57 2, /* e min */
58 2, /* f max */
59 1, /* 10 flr */
60 1, /* 11 mod */
61 1, /* 12 trc */
62 2, /* 13 sge */
63 2, /* 14 slt */
64 1,
65 1,
66 1,
67 1,
68 0,
69 0,
70 0,
71 0,
72 0,
73 0,
74 0,
75 };
76
77
78 static const char *regname[0x8] = {
79 "R",
80 "T",
81 "CONST",
82 "S",
83 "OC",
84 "OD",
85 "U",
86 "UNKNOWN",
87 };
88
89 static void print_reg_type_nr( GLuint type, GLuint nr )
90 {
91 switch (type) {
92 case REG_TYPE_T:
93 switch (nr) {
94 case T_DIFFUSE: fprintf(stderr, "T_DIFFUSE"); return;
95 case T_SPECULAR: fprintf(stderr, "T_SPECULAR"); return;
96 case T_FOG_W: fprintf(stderr, "T_FOG_W"); return;
97 default: fprintf(stderr, "T_TEX%d", nr); return;
98 }
99 case REG_TYPE_OC:
100 if (nr == 0) {
101 fprintf(stderr, "oC");
102 return;
103 }
104 break;
105 case REG_TYPE_OD:
106 if (nr == 0) {
107 fprintf(stderr, "oD");
108 return;
109 }
110 break;
111 default:
112 break;
113 }
114
115 fprintf(stderr, "%s[%d]", regname[type], nr);
116 }
117
118 #define REG_SWIZZLE_MASK 0x7777
119 #define REG_NEGATE_MASK 0x8888
120
121 #define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \
122 (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \
123 (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \
124 (SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
125
126
127 static void print_reg_neg_swizzle( GLuint reg )
128 {
129 int i;
130
131 if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW &&
132 (reg & REG_NEGATE_MASK) == 0)
133 return;
134
135 fprintf(stderr, ".");
136
137 for (i = 3 ; i >= 0; i--) {
138 if (reg & (1<<((i*4)+3)))
139 fprintf(stderr, "-");
140
141 switch ((reg>>(i*4)) & 0x7) {
142 case 0: fprintf(stderr, "x"); break;
143 case 1: fprintf(stderr, "y"); break;
144 case 2: fprintf(stderr, "z"); break;
145 case 3: fprintf(stderr, "w"); break;
146 case 4: fprintf(stderr, "0"); break;
147 case 5: fprintf(stderr, "1"); break;
148 default: fprintf(stderr, "?"); break;
149 }
150 }
151 }
152
153
154 static void print_src_reg( GLuint dword )
155 {
156 GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK;
157 GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK;
158 print_reg_type_nr( type, nr );
159 print_reg_neg_swizzle( dword );
160 }
161
162 void i915_print_ureg( const char *msg, GLuint ureg )
163 {
164 fprintf(stderr, "%s: ", msg);
165 print_src_reg( ureg >> 8 );
166 fprintf(stderr, "\n");
167 }
168
169 static void print_dest_reg( GLuint dword )
170 {
171 GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK;
172 GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK;
173 print_reg_type_nr( type, nr );
174 if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL)
175 return;
176 fprintf(stderr, ".");
177 if (dword & A0_DEST_CHANNEL_X) fprintf(stderr, "x");
178 if (dword & A0_DEST_CHANNEL_Y) fprintf(stderr, "y");
179 if (dword & A0_DEST_CHANNEL_Z) fprintf(stderr, "z");
180 if (dword & A0_DEST_CHANNEL_W) fprintf(stderr, "w");
181 }
182
183
184 #define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT))
185 #define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT))
186 #define GET_SRC2_REG(r) (r)
187
188
189 static void print_arith_op( GLuint opcode, const GLuint *program )
190 {
191 if (opcode != A0_NOP) {
192 print_dest_reg(program[0]);
193 if (program[0] & A0_DEST_SATURATE)
194 fprintf(stderr, " = SATURATE ");
195 else
196 fprintf(stderr, " = ");
197 }
198
199 fprintf(stderr, "%s ", opcodes[opcode]);
200
201 print_src_reg(GET_SRC0_REG(program[0], program[1]));
202 if (args[opcode] == 1) {
203 fprintf(stderr, "\n");
204 return;
205 }
206
207 fprintf(stderr, ", ");
208 print_src_reg(GET_SRC1_REG(program[1], program[2]));
209 if (args[opcode] == 2) {
210 fprintf(stderr, "\n");
211 return;
212 }
213
214 fprintf(stderr, ", ");
215 print_src_reg(GET_SRC2_REG(program[2]));
216 fprintf(stderr, "\n");
217 return;
218 }
219
220
221 static void print_tex_op( GLuint opcode, const GLuint *program )
222 {
223 print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
224 fprintf(stderr, " = ");
225
226 fprintf(stderr, "%s ", opcodes[opcode]);
227
228 fprintf(stderr, "S[%d],",
229 program[0] & T0_SAMPLER_NR_MASK);
230
231 print_reg_type_nr( (program[1]>>T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK,
232 (program[1]>>T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK );
233 fprintf(stderr, "\n");
234 }
235
236 static void print_dcl_op( GLuint opcode, const GLuint *program )
237 {
238 fprintf(stderr, "%s ", opcodes[opcode]);
239 print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
240 fprintf(stderr, "\n");
241 }
242
243
244 void i915_disassemble_program( const GLuint *program, GLuint sz )
245 {
246 GLuint size = program[0] & 0x1ff;
247 GLint i;
248
249 fprintf(stderr, "BEGIN\n");
250
251 if (size+2 != sz) {
252 fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__,
253 size+2, sz);
254 exit(1);
255 }
256
257 program ++;
258 for (i = 1 ; i < sz ; i+=3, program+=3) {
259 GLuint opcode = program[0] & (0x1f<<24);
260
261 if (opcode >= A0_NOP && opcode <= A0_SLT)
262 print_arith_op(opcode >> 24, program);
263 else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL)
264 print_tex_op(opcode >> 24, program);
265 else if (opcode == D0_DCL)
266 print_dcl_op(opcode >> 24, program);
267 else
268 fprintf(stderr, "Unknown opcode 0x%x\n", opcode);
269 }
270
271 fprintf(stderr, "END\n\n");
272 }