Merge remote branch 'origin/master' into gallium_draw_llvm
[mesa.git] / src / mesa / drivers / dri / intel / intel_decode.c
1 /* -*- c-basic-offset: 4 -*- */
2 /*
3 * Copyright © 2007 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
26 *
27 */
28
29 /** @file intel_decode.c
30 * This file contains code to print out batchbuffer contents in a
31 * human-readable format.
32 *
33 * The current version only supports i915 packets, and only pretty-prints a
34 * subset of them. The intention is for it to make just a best attempt to
35 * decode, but never crash in the process.
36 */
37
38 #include <stdio.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <inttypes.h>
42
43 #include "intel_decode.h"
44 #include "intel_chipset.h"
45
46 #define BUFFER_FAIL(_count, _len, _name) do { \
47 fprintf(out, "Buffer size too small in %s (%d < %d)\n", \
48 (_name), (_count), (_len)); \
49 (*failures)++; \
50 return count; \
51 } while (0)
52
53 static FILE *out;
54 static uint32_t saved_s2 = 0, saved_s4 = 0;
55 static char saved_s2_set = 0, saved_s4_set = 0;
56
57 static float
58 int_as_float(uint32_t intval)
59 {
60 union intfloat {
61 uint32_t i;
62 float f;
63 } uval;
64
65 uval.i = intval;
66 return uval.f;
67 }
68
69 static void
70 instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index,
71 char *fmt, ...)
72 {
73 va_list va;
74
75 fprintf(out, "0x%08x: 0x%08x:%s ", hw_offset + index * 4, data[index],
76 index == 0 ? "" : " ");
77 va_start(va, fmt);
78 vfprintf(out, fmt, va);
79 va_end(va);
80 }
81
82
83 static int
84 decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)
85 {
86 unsigned int opcode;
87
88 struct {
89 uint32_t opcode;
90 int len_mask;
91 int min_len;
92 int max_len;
93 char *name;
94 } opcodes_mi[] = {
95 { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" },
96 { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" },
97 { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" },
98 { 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" },
99 { 0x04, 0, 1, 1, "MI_FLUSH" },
100 { 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" },
101 { 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" },
102 { 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" },
103 { 0x00, 0, 1, 1, "MI_NOOP" },
104 { 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" },
105 { 0x07, 0, 1, 1, "MI_REPORT_HEAD" },
106 { 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" },
107 { 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" },
108 { 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" },
109 { 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" },
110 { 0x02, 0, 1, 1, "MI_USER_INTERRUPT" },
111 { 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" },
112 };
113
114
115 for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]);
116 opcode++) {
117 if ((data[0] & 0x1f800000) >> 23 == opcodes_mi[opcode].opcode) {
118 unsigned int len = 1, i;
119
120 instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name);
121 if (opcodes_mi[opcode].max_len > 1) {
122 len = (data[0] & opcodes_mi[opcode].len_mask) + 2;
123 if (len < opcodes_mi[opcode].min_len ||
124 len > opcodes_mi[opcode].max_len)
125 {
126 fprintf(out, "Bad length (%d) in %s, [%d, %d]\n",
127 len, opcodes_mi[opcode].name,
128 opcodes_mi[opcode].min_len,
129 opcodes_mi[opcode].max_len);
130 }
131 }
132
133 for (i = 1; i < len; i++) {
134 if (i >= count)
135 BUFFER_FAIL(count, len, opcodes_mi[opcode].name);
136 instr_out(data, hw_offset, i, "dword %d\n", i);
137 }
138
139 return len;
140 }
141 }
142
143 instr_out(data, hw_offset, 0, "MI UNKNOWN\n");
144 (*failures)++;
145 return 1;
146 }
147
148 static int
149 decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
150 {
151 unsigned int opcode, len;
152 char *format = NULL;
153
154 struct {
155 uint32_t opcode;
156 int min_len;
157 int max_len;
158 char *name;
159 } opcodes_2d[] = {
160 { 0x40, 5, 5, "COLOR_BLT" },
161 { 0x43, 6, 6, "SRC_COPY_BLT" },
162 { 0x01, 8, 8, "XY_SETUP_BLT" },
163 { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" },
164 { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" },
165 { 0x24, 2, 2, "XY_PIXEL_BLT" },
166 { 0x25, 3, 3, "XY_SCANLINES_BLT" },
167 { 0x26, 4, 4, "Y_TEXT_BLT" },
168 { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" },
169 { 0x50, 6, 6, "XY_COLOR_BLT" },
170 { 0x51, 6, 6, "XY_PAT_BLT" },
171 { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" },
172 { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" },
173 { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" },
174 { 0x52, 9, 9, "XY_MONO_PAT_BLT" },
175 { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" },
176 { 0x53, 8, 8, "XY_SRC_COPY_BLT" },
177 { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" },
178 { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" },
179 { 0x55, 9, 9, "XY_FULL_BLT" },
180 { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" },
181 { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" },
182 { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" },
183 { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" },
184 { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" },
185 };
186
187 switch ((data[0] & 0x1fc00000) >> 22) {
188 case 0x50:
189 instr_out(data, hw_offset, 0,
190 "XY_COLOR_BLT (rgb %sabled, alpha %sabled, dst tile %d)\n",
191 (data[0] & (1 << 20)) ? "en" : "dis",
192 (data[0] & (1 << 21)) ? "en" : "dis",
193 (data[0] >> 11) & 1);
194
195 len = (data[0] & 0x000000ff) + 2;
196 if (len != 6)
197 fprintf(out, "Bad count in XY_COLOR_BLT\n");
198 if (count < 6)
199 BUFFER_FAIL(count, len, "XY_COLOR_BLT");
200
201 switch ((data[1] >> 24) & 0x3) {
202 case 0:
203 format="8";
204 break;
205 case 1:
206 format="565";
207 break;
208 case 2:
209 format="1555";
210 break;
211 case 3:
212 format="8888";
213 break;
214 }
215
216 instr_out(data, hw_offset, 1, "format %s, pitch %d, "
217 "clipping %sabled\n", format,
218 (short)(data[1] & 0xffff),
219 data[1] & (1 << 30) ? "en" : "dis");
220 instr_out(data, hw_offset, 2, "(%d,%d)\n",
221 data[2] & 0xffff, data[2] >> 16);
222 instr_out(data, hw_offset, 3, "(%d,%d)\n",
223 data[3] & 0xffff, data[3] >> 16);
224 instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]);
225 instr_out(data, hw_offset, 5, "color\n");
226 return len;
227 case 0x53:
228 instr_out(data, hw_offset, 0,
229 "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled, "
230 "src tile %d, dst tile %d)\n",
231 (data[0] & (1 << 20)) ? "en" : "dis",
232 (data[0] & (1 << 21)) ? "en" : "dis",
233 (data[0] >> 15) & 1,
234 (data[0] >> 11) & 1);
235
236 len = (data[0] & 0x000000ff) + 2;
237 if (len != 8)
238 fprintf(out, "Bad count in XY_SRC_COPY_BLT\n");
239 if (count < 8)
240 BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT");
241
242 switch ((data[1] >> 24) & 0x3) {
243 case 0:
244 format="8";
245 break;
246 case 1:
247 format="565";
248 break;
249 case 2:
250 format="1555";
251 break;
252 case 3:
253 format="8888";
254 break;
255 }
256
257 instr_out(data, hw_offset, 1, "format %s, dst pitch %d, "
258 "clipping %sabled\n", format,
259 (short)(data[1] & 0xffff),
260 data[1] & (1 << 30) ? "en" : "dis");
261 instr_out(data, hw_offset, 2, "dst (%d,%d)\n",
262 data[2] & 0xffff, data[2] >> 16);
263 instr_out(data, hw_offset, 3, "dst (%d,%d)\n",
264 data[3] & 0xffff, data[3] >> 16);
265 instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]);
266 instr_out(data, hw_offset, 5, "src (%d,%d)\n",
267 data[5] & 0xffff, data[5] >> 16);
268 instr_out(data, hw_offset, 6, "src pitch %d\n",
269 (short)(data[6] & 0xffff));
270 instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]);
271 return len;
272 }
273
274 for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]);
275 opcode++) {
276 if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) {
277 unsigned int i;
278
279 len = 1;
280 instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name);
281 if (opcodes_2d[opcode].max_len > 1) {
282 len = (data[0] & 0x000000ff) + 2;
283 if (len < opcodes_2d[opcode].min_len ||
284 len > opcodes_2d[opcode].max_len)
285 {
286 fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name);
287 }
288 }
289
290 for (i = 1; i < len; i++) {
291 if (i >= count)
292 BUFFER_FAIL(count, len, opcodes_2d[opcode].name);
293 instr_out(data, hw_offset, i, "dword %d\n", i);
294 }
295
296 return len;
297 }
298 }
299
300 instr_out(data, hw_offset, 0, "2D UNKNOWN\n");
301 (*failures)++;
302 return 1;
303 }
304
305 static int
306 decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
307 {
308 switch ((data[0] & 0x00f80000) >> 19) {
309 case 0x11:
310 instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n");
311 return 1;
312 case 0x10:
313 instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n");
314 return 1;
315 case 0x01:
316 instr_out(data, hw_offset, 0, "3DSTATE_MAP_COORD_SET_I830\n");
317 return 1;
318 case 0x0a:
319 instr_out(data, hw_offset, 0, "3DSTATE_MAP_CUBE_I830\n");
320 return 1;
321 case 0x05:
322 instr_out(data, hw_offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n");
323 return 1;
324 }
325
326 instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
327 (*failures)++;
328 return 1;
329 }
330
331 /** Sets the string dstname to describe the destination of the PS instruction */
332 static void
333 i915_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask)
334 {
335 uint32_t a0 = data[i];
336 int dst_nr = (a0 >> 14) & 0xf;
337 char dstmask[8];
338 char *sat;
339
340 if (do_mask) {
341 if (((a0 >> 10) & 0xf) == 0xf) {
342 dstmask[0] = 0;
343 } else {
344 int dstmask_index = 0;
345
346 dstmask[dstmask_index++] = '.';
347 if (a0 & (1 << 10))
348 dstmask[dstmask_index++] = 'x';
349 if (a0 & (1 << 11))
350 dstmask[dstmask_index++] = 'y';
351 if (a0 & (1 << 12))
352 dstmask[dstmask_index++] = 'z';
353 if (a0 & (1 << 13))
354 dstmask[dstmask_index++] = 'w';
355 dstmask[dstmask_index++] = 0;
356 }
357
358 if (a0 & (1 << 22))
359 sat = ".sat";
360 else
361 sat = "";
362 } else {
363 dstmask[0] = 0;
364 sat = "";
365 }
366
367 switch ((a0 >> 19) & 0x7) {
368 case 0:
369 if (dst_nr > 15)
370 fprintf(out, "bad destination reg R%d\n", dst_nr);
371 sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat);
372 break;
373 case 4:
374 if (dst_nr > 0)
375 fprintf(out, "bad destination reg oC%d\n", dst_nr);
376 sprintf(dstname, "oC%s%s", dstmask, sat);
377 break;
378 case 5:
379 if (dst_nr > 0)
380 fprintf(out, "bad destination reg oD%d\n", dst_nr);
381 sprintf(dstname, "oD%s%s", dstmask, sat);
382 break;
383 case 6:
384 if (dst_nr > 2)
385 fprintf(out, "bad destination reg U%d\n", dst_nr);
386 sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);
387 break;
388 default:
389 sprintf(dstname, "RESERVED");
390 break;
391 }
392 }
393
394 static char *
395 i915_get_channel_swizzle(uint32_t select)
396 {
397 switch (select & 0x7) {
398 case 0:
399 return (select & 8) ? "-x" : "x";
400 case 1:
401 return (select & 8) ? "-y" : "y";
402 case 2:
403 return (select & 8) ? "-z" : "z";
404 case 3:
405 return (select & 8) ? "-w" : "w";
406 case 4:
407 return (select & 8) ? "-0" : "0";
408 case 5:
409 return (select & 8) ? "-1" : "1";
410 default:
411 return (select & 8) ? "-bad" : "bad";
412 }
413 }
414
415 static void
416 i915_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)
417 {
418 switch (src_type) {
419 case 0:
420 sprintf(name, "R%d", src_nr);
421 if (src_nr > 15)
422 fprintf(out, "bad src reg %s\n", name);
423 break;
424 case 1:
425 if (src_nr < 8)
426 sprintf(name, "T%d", src_nr);
427 else if (src_nr == 8)
428 sprintf(name, "DIFFUSE");
429 else if (src_nr == 9)
430 sprintf(name, "SPECULAR");
431 else if (src_nr == 10)
432 sprintf(name, "FOG");
433 else {
434 fprintf(out, "bad src reg T%d\n", src_nr);
435 sprintf(name, "RESERVED");
436 }
437 break;
438 case 2:
439 sprintf(name, "C%d", src_nr);
440 if (src_nr > 31)
441 fprintf(out, "bad src reg %s\n", name);
442 break;
443 case 4:
444 sprintf(name, "oC");
445 if (src_nr > 0)
446 fprintf(out, "bad src reg oC%d\n", src_nr);
447 break;
448 case 5:
449 sprintf(name, "oD");
450 if (src_nr > 0)
451 fprintf(out, "bad src reg oD%d\n", src_nr);
452 break;
453 case 6:
454 sprintf(name, "U%d", src_nr);
455 if (src_nr > 2)
456 fprintf(out, "bad src reg %s\n", name);
457 break;
458 default:
459 fprintf(out, "bad src reg type %d\n", src_type);
460 sprintf(name, "RESERVED");
461 break;
462 }
463 }
464
465 static void
466 i915_get_instruction_src0(uint32_t *data, int i, char *srcname)
467 {
468 uint32_t a0 = data[i];
469 uint32_t a1 = data[i + 1];
470 int src_nr = (a0 >> 2) & 0x1f;
471 char *swizzle_x = i915_get_channel_swizzle((a1 >> 28) & 0xf);
472 char *swizzle_y = i915_get_channel_swizzle((a1 >> 24) & 0xf);
473 char *swizzle_z = i915_get_channel_swizzle((a1 >> 20) & 0xf);
474 char *swizzle_w = i915_get_channel_swizzle((a1 >> 16) & 0xf);
475 char swizzle[100];
476
477 i915_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname);
478 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
479 if (strcmp(swizzle, ".xyzw") != 0)
480 strcat(srcname, swizzle);
481 }
482
483 static void
484 i915_get_instruction_src1(uint32_t *data, int i, char *srcname)
485 {
486 uint32_t a1 = data[i + 1];
487 uint32_t a2 = data[i + 2];
488 int src_nr = (a1 >> 8) & 0x1f;
489 char *swizzle_x = i915_get_channel_swizzle((a1 >> 4) & 0xf);
490 char *swizzle_y = i915_get_channel_swizzle((a1 >> 0) & 0xf);
491 char *swizzle_z = i915_get_channel_swizzle((a2 >> 28) & 0xf);
492 char *swizzle_w = i915_get_channel_swizzle((a2 >> 24) & 0xf);
493 char swizzle[100];
494
495 i915_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname);
496 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
497 if (strcmp(swizzle, ".xyzw") != 0)
498 strcat(srcname, swizzle);
499 }
500
501 static void
502 i915_get_instruction_src2(uint32_t *data, int i, char *srcname)
503 {
504 uint32_t a2 = data[i + 2];
505 int src_nr = (a2 >> 16) & 0x1f;
506 char *swizzle_x = i915_get_channel_swizzle((a2 >> 12) & 0xf);
507 char *swizzle_y = i915_get_channel_swizzle((a2 >> 8) & 0xf);
508 char *swizzle_z = i915_get_channel_swizzle((a2 >> 4) & 0xf);
509 char *swizzle_w = i915_get_channel_swizzle((a2 >> 0) & 0xf);
510 char swizzle[100];
511
512 i915_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname);
513 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
514 if (strcmp(swizzle, ".xyzw") != 0)
515 strcat(srcname, swizzle);
516 }
517
518 static void
519 i915_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name)
520 {
521 switch (src_type) {
522 case 0:
523 sprintf(name, "R%d", src_nr);
524 if (src_nr > 15)
525 fprintf(out, "bad src reg %s\n", name);
526 break;
527 case 1:
528 if (src_nr < 8)
529 sprintf(name, "T%d", src_nr);
530 else if (src_nr == 8)
531 sprintf(name, "DIFFUSE");
532 else if (src_nr == 9)
533 sprintf(name, "SPECULAR");
534 else if (src_nr == 10)
535 sprintf(name, "FOG");
536 else {
537 fprintf(out, "bad src reg T%d\n", src_nr);
538 sprintf(name, "RESERVED");
539 }
540 break;
541 case 4:
542 sprintf(name, "oC");
543 if (src_nr > 0)
544 fprintf(out, "bad src reg oC%d\n", src_nr);
545 break;
546 case 5:
547 sprintf(name, "oD");
548 if (src_nr > 0)
549 fprintf(out, "bad src reg oD%d\n", src_nr);
550 break;
551 default:
552 fprintf(out, "bad src reg type %d\n", src_type);
553 sprintf(name, "RESERVED");
554 break;
555 }
556 }
557
558 static void
559 i915_decode_alu1(uint32_t *data, uint32_t hw_offset,
560 int i, char *instr_prefix, char *op_name)
561 {
562 char dst[100], src0[100];
563
564 i915_get_instruction_dst(data, i, dst, 1);
565 i915_get_instruction_src0(data, i, src0);
566
567 instr_out(data, hw_offset, i++, "%s: %s %s, %s\n", instr_prefix,
568 op_name, dst, src0);
569 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
570 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
571 }
572
573 static void
574 i915_decode_alu2(uint32_t *data, uint32_t hw_offset,
575 int i, char *instr_prefix, char *op_name)
576 {
577 char dst[100], src0[100], src1[100];
578
579 i915_get_instruction_dst(data, i, dst, 1);
580 i915_get_instruction_src0(data, i, src0);
581 i915_get_instruction_src1(data, i, src1);
582
583 instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s\n", instr_prefix,
584 op_name, dst, src0, src1);
585 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
586 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
587 }
588
589 static void
590 i915_decode_alu3(uint32_t *data, uint32_t hw_offset,
591 int i, char *instr_prefix, char *op_name)
592 {
593 char dst[100], src0[100], src1[100], src2[100];
594
595 i915_get_instruction_dst(data, i, dst, 1);
596 i915_get_instruction_src0(data, i, src0);
597 i915_get_instruction_src1(data, i, src1);
598 i915_get_instruction_src2(data, i, src2);
599
600 instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix,
601 op_name, dst, src0, src1, src2);
602 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
603 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
604 }
605
606 static void
607 i915_decode_tex(uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix,
608 char *tex_name)
609 {
610 uint32_t t0 = data[i];
611 uint32_t t1 = data[i + 1];
612 char dst_name[100];
613 char addr_name[100];
614 int sampler_nr;
615
616 i915_get_instruction_dst(data, i, dst_name, 0);
617 i915_get_instruction_addr((t1 >> 24) & 0x7,
618 (t1 >> 17) & 0xf,
619 addr_name);
620 sampler_nr = t0 & 0xf;
621
622 instr_out(data, hw_offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix,
623 tex_name, dst_name, sampler_nr, addr_name);
624 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
625 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
626 }
627
628 static void
629 i915_decode_dcl(uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix)
630 {
631 uint32_t d0 = data[i];
632 char *sampletype;
633 int dcl_nr = (d0 >> 14) & 0xf;
634 char *dcl_x = d0 & (1 << 10) ? "x" : "";
635 char *dcl_y = d0 & (1 << 11) ? "y" : "";
636 char *dcl_z = d0 & (1 << 12) ? "z" : "";
637 char *dcl_w = d0 & (1 << 13) ? "w" : "";
638 char dcl_mask[10];
639
640 switch ((d0 >> 19) & 0x3) {
641 case 1:
642 sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w);
643 if (strcmp(dcl_mask, ".") == 0)
644 fprintf(out, "bad (empty) dcl mask\n");
645
646 if (dcl_nr > 10)
647 fprintf(out, "bad T%d dcl register number\n", dcl_nr);
648 if (dcl_nr < 8) {
649 if (strcmp(dcl_mask, ".x") != 0 &&
650 strcmp(dcl_mask, ".xy") != 0 &&
651 strcmp(dcl_mask, ".xz") != 0 &&
652 strcmp(dcl_mask, ".w") != 0 &&
653 strcmp(dcl_mask, ".xyzw") != 0) {
654 fprintf(out, "bad T%d.%s dcl mask\n", dcl_nr, dcl_mask);
655 }
656 instr_out(data, hw_offset, i++, "%s: DCL T%d%s\n", instr_prefix,
657 dcl_nr, dcl_mask);
658 } else {
659 if (strcmp(dcl_mask, ".xz") == 0)
660 fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
661 else if (strcmp(dcl_mask, ".xw") == 0)
662 fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
663 else if (strcmp(dcl_mask, ".xzw") == 0)
664 fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
665
666 if (dcl_nr == 8) {
667 instr_out(data, hw_offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix,
668 dcl_mask);
669 } else if (dcl_nr == 9) {
670 instr_out(data, hw_offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix,
671 dcl_mask);
672 } else if (dcl_nr == 10) {
673 instr_out(data, hw_offset, i++, "%s: DCL FOG%s\n", instr_prefix,
674 dcl_mask);
675 }
676 }
677 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
678 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
679 break;
680 case 3:
681 switch ((d0 >> 22) & 0x3) {
682 case 0:
683 sampletype = "2D";
684 break;
685 case 1:
686 sampletype = "CUBE";
687 break;
688 case 2:
689 sampletype = "3D";
690 break;
691 default:
692 sampletype = "RESERVED";
693 break;
694 }
695 if (dcl_nr > 15)
696 fprintf(out, "bad S%d dcl register number\n", dcl_nr);
697 instr_out(data, hw_offset, i++, "%s: DCL S%d %s\n", instr_prefix,
698 dcl_nr, sampletype);
699 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
700 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
701 break;
702 default:
703 instr_out(data, hw_offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr);
704 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
705 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
706 }
707 }
708
709 static void
710 i915_decode_instruction(uint32_t *data, uint32_t hw_offset,
711 int i, char *instr_prefix)
712 {
713 switch ((data[i] >> 24) & 0x1f) {
714 case 0x0:
715 instr_out(data, hw_offset, i++, "%s: NOP\n", instr_prefix);
716 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
717 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
718 break;
719 case 0x01:
720 i915_decode_alu2(data, hw_offset, i, instr_prefix, "ADD");
721 break;
722 case 0x02:
723 i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOV");
724 break;
725 case 0x03:
726 i915_decode_alu2(data, hw_offset, i, instr_prefix, "MUL");
727 break;
728 case 0x04:
729 i915_decode_alu3(data, hw_offset, i, instr_prefix, "MAD");
730 break;
731 case 0x05:
732 i915_decode_alu3(data, hw_offset, i, instr_prefix, "DP2ADD");
733 break;
734 case 0x06:
735 i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP3");
736 break;
737 case 0x07:
738 i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP4");
739 break;
740 case 0x08:
741 i915_decode_alu1(data, hw_offset, i, instr_prefix, "FRC");
742 break;
743 case 0x09:
744 i915_decode_alu1(data, hw_offset, i, instr_prefix, "RCP");
745 break;
746 case 0x0a:
747 i915_decode_alu1(data, hw_offset, i, instr_prefix, "RSQ");
748 break;
749 case 0x0b:
750 i915_decode_alu1(data, hw_offset, i, instr_prefix, "EXP");
751 break;
752 case 0x0c:
753 i915_decode_alu1(data, hw_offset, i, instr_prefix, "LOG");
754 break;
755 case 0x0d:
756 i915_decode_alu2(data, hw_offset, i, instr_prefix, "CMP");
757 break;
758 case 0x0e:
759 i915_decode_alu2(data, hw_offset, i, instr_prefix, "MIN");
760 break;
761 case 0x0f:
762 i915_decode_alu2(data, hw_offset, i, instr_prefix, "MAX");
763 break;
764 case 0x10:
765 i915_decode_alu1(data, hw_offset, i, instr_prefix, "FLR");
766 break;
767 case 0x11:
768 i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOD");
769 break;
770 case 0x12:
771 i915_decode_alu1(data, hw_offset, i, instr_prefix, "TRC");
772 break;
773 case 0x13:
774 i915_decode_alu2(data, hw_offset, i, instr_prefix, "SGE");
775 break;
776 case 0x14:
777 i915_decode_alu2(data, hw_offset, i, instr_prefix, "SLT");
778 break;
779 case 0x15:
780 i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLD");
781 break;
782 case 0x16:
783 i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDP");
784 break;
785 case 0x17:
786 i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDB");
787 break;
788 case 0x19:
789 i915_decode_dcl(data, hw_offset, i, instr_prefix);
790 break;
791 default:
792 instr_out(data, hw_offset, i++, "%s: unknown\n", instr_prefix);
793 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
794 instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
795 break;
796 }
797 }
798
799 static int
800 decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830)
801 {
802 unsigned int len, i, c, opcode, word, map, sampler, instr;
803 char *format;
804
805 struct {
806 uint32_t opcode;
807 int i830_only;
808 int min_len;
809 int max_len;
810 char *name;
811 } opcodes_3d_1d[] = {
812 { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
813 { 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" },
814 { 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
815 { 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
816 { 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
817 { 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
818 { 0x98, 0, 2, 2, "3DSTATE_DEFAULT_Z" },
819 { 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
820 { 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
821 { 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
822 { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
823 { 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
824 { 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" },
825 { 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" },
826 { 0x8f, 0, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
827 { 0x81, 0, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" },
828 { 0x83, 0, 2, 2, "3DSTATE_SPAN_STIPPLE" },
829 { 0x8c, 1, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM_I830" },
830 { 0x8b, 1, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM_I830" },
831 { 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" },
832 { 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" },
833 { 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" },
834 };
835
836 switch ((data[0] & 0x00ff0000) >> 16) {
837 case 0x07:
838 /* This instruction is unusual. A 0 length means just 1 DWORD instead of
839 * 2. The 0 length is specified in one place to be unsupported, but
840 * stated to be required in another, and 0 length LOAD_INDIRECTs appear
841 * to cause no harm at least.
842 */
843 instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n");
844 len = (data[0] & 0x000000ff) + 1;
845 i = 1;
846 if (data[0] & (0x01 << 8)) {
847 if (i + 2 >= count)
848 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
849 instr_out(data, hw_offset, i++, "SIS.0\n");
850 instr_out(data, hw_offset, i++, "SIS.1\n");
851 }
852 if (data[0] & (0x02 << 8)) {
853 if (i + 1 >= count)
854 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
855 instr_out(data, hw_offset, i++, "DIS.0\n");
856 }
857 if (data[0] & (0x04 << 8)) {
858 if (i + 2 >= count)
859 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
860 instr_out(data, hw_offset, i++, "SSB.0\n");
861 instr_out(data, hw_offset, i++, "SSB.1\n");
862 }
863 if (data[0] & (0x08 << 8)) {
864 if (i + 2 >= count)
865 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
866 instr_out(data, hw_offset, i++, "MSB.0\n");
867 instr_out(data, hw_offset, i++, "MSB.1\n");
868 }
869 if (data[0] & (0x10 << 8)) {
870 if (i + 2 >= count)
871 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
872 instr_out(data, hw_offset, i++, "PSP.0\n");
873 instr_out(data, hw_offset, i++, "PSP.1\n");
874 }
875 if (data[0] & (0x20 << 8)) {
876 if (i + 2 >= count)
877 BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
878 instr_out(data, hw_offset, i++, "PSC.0\n");
879 instr_out(data, hw_offset, i++, "PSC.1\n");
880 }
881 if (len != i) {
882 fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
883 (*failures)++;
884 return len;
885 }
886 return len;
887 case 0x04:
888 instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
889 len = (data[0] & 0x0000000f) + 2;
890 i = 1;
891 for (word = 0; word <= 7; word++) {
892 if (data[0] & (1 << (4 + word))) {
893 if (i >= count)
894 BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1");
895
896 /* save vertex state for decode */
897 if (word == 2) {
898 saved_s2_set = 1;
899 saved_s2 = data[i];
900 }
901 if (word == 4) {
902 saved_s4_set = 1;
903 saved_s4 = data[i];
904 }
905
906 instr_out(data, hw_offset, i++, "S%d\n", word);
907 }
908 }
909 if (len != i) {
910 fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
911 (*failures)++;
912 }
913 return len;
914 case 0x00:
915 instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n");
916 len = (data[0] & 0x0000003f) + 2;
917 instr_out(data, hw_offset, 1, "mask\n");
918
919 i = 2;
920 for (map = 0; map <= 15; map++) {
921 if (data[1] & (1 << map)) {
922 if (i + 3 >= count)
923 BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE");
924 instr_out(data, hw_offset, i++, "map %d MS2\n", map);
925 instr_out(data, hw_offset, i++, "map %d MS3\n", map);
926 instr_out(data, hw_offset, i++, "map %d MS4\n", map);
927 }
928 }
929 if (len != i) {
930 fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n");
931 (*failures)++;
932 return len;
933 }
934 return len;
935 case 0x06:
936 instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n");
937 len = (data[0] & 0x000000ff) + 2;
938
939 i = 2;
940 for (c = 0; c <= 31; c++) {
941 if (data[1] & (1 << c)) {
942 if (i + 4 >= count)
943 BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS");
944 instr_out(data, hw_offset, i, "C%d.X = %f\n",
945 c, int_as_float(data[i]));
946 i++;
947 instr_out(data, hw_offset, i, "C%d.Y = %f\n",
948 c, int_as_float(data[i]));
949 i++;
950 instr_out(data, hw_offset, i, "C%d.Z = %f\n",
951 c, int_as_float(data[i]));
952 i++;
953 instr_out(data, hw_offset, i, "C%d.W = %f\n",
954 c, int_as_float(data[i]));
955 i++;
956 }
957 }
958 if (len != i) {
959 fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_CONSTANTS\n");
960 (*failures)++;
961 }
962 return len;
963 case 0x05:
964 instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n");
965 len = (data[0] & 0x000000ff) + 2;
966 if ((len - 1) % 3 != 0 || len > 370) {
967 fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n");
968 (*failures)++;
969 }
970 i = 1;
971 for (instr = 0; instr < (len - 1) / 3; instr++) {
972 char instr_prefix[10];
973
974 if (i + 3 >= count)
975 BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_PROGRAM");
976 sprintf(instr_prefix, "PS%03d", instr);
977 i915_decode_instruction(data, hw_offset, i, instr_prefix);
978 i += 3;
979 }
980 return len;
981 case 0x01:
982 if (i830)
983 break;
984 instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");
985 instr_out(data, hw_offset, 1, "mask\n");
986 len = (data[0] & 0x0000003f) + 2;
987 i = 2;
988 for (sampler = 0; sampler <= 15; sampler++) {
989 if (data[1] & (1 << sampler)) {
990 if (i + 3 >= count)
991 BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE");
992 instr_out(data, hw_offset, i++, "sampler %d SS2\n",
993 sampler);
994 instr_out(data, hw_offset, i++, "sampler %d SS3\n",
995 sampler);
996 instr_out(data, hw_offset, i++, "sampler %d SS4\n",
997 sampler);
998 }
999 }
1000 if (len != i) {
1001 fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n");
1002 (*failures)++;
1003 }
1004 return len;
1005 case 0x85:
1006 len = (data[0] & 0x0000000f) + 2;
1007
1008 if (len != 2)
1009 fprintf(out, "Bad count in 3DSTATE_DEST_BUFFER_VARIABLES\n");
1010 if (count < 2)
1011 BUFFER_FAIL(count, len, "3DSTATE_DEST_BUFFER_VARIABLES");
1012
1013 instr_out(data, hw_offset, 0,
1014 "3DSTATE_DEST_BUFFER_VARIABLES\n");
1015
1016 switch ((data[1] >> 8) & 0xf) {
1017 case 0x0: format = "g8"; break;
1018 case 0x1: format = "x1r5g5b5"; break;
1019 case 0x2: format = "r5g6b5"; break;
1020 case 0x3: format = "a8r8g8b8"; break;
1021 case 0x4: format = "ycrcb_swapy"; break;
1022 case 0x5: format = "ycrcb_normal"; break;
1023 case 0x6: format = "ycrcb_swapuv"; break;
1024 case 0x7: format = "ycrcb_swapuvy"; break;
1025 case 0x8: format = "a4r4g4b4"; break;
1026 case 0x9: format = "a1r5g5b5"; break;
1027 case 0xa: format = "a2r10g10b10"; break;
1028 default: format = "BAD"; break;
1029 }
1030 instr_out(data, hw_offset, 1, "%s format, early Z %sabled\n",
1031 format,
1032 (data[1] & (1 << 31)) ? "en" : "dis");
1033 return len;
1034 }
1035
1036 for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]);
1037 opcode++)
1038 {
1039 if (opcodes_3d_1d[opcode].i830_only && !i830)
1040 continue;
1041
1042 if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) {
1043 len = 1;
1044
1045 instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name);
1046 if (opcodes_3d_1d[opcode].max_len > 1) {
1047 len = (data[0] & 0x0000ffff) + 2;
1048 if (len < opcodes_3d_1d[opcode].min_len ||
1049 len > opcodes_3d_1d[opcode].max_len)
1050 {
1051 fprintf(out, "Bad count in %s\n",
1052 opcodes_3d_1d[opcode].name);
1053 (*failures)++;
1054 }
1055 }
1056
1057 for (i = 1; i < len; i++) {
1058 if (i >= count)
1059 BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name);
1060 instr_out(data, hw_offset, i, "dword %d\n", i);
1061 }
1062
1063 return len;
1064 }
1065 }
1066
1067 instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
1068 (*failures)++;
1069 return 1;
1070 }
1071
1072 static int
1073 decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
1074 int *failures)
1075 {
1076 char immediate = (data[0] & (1 << 23)) == 0;
1077 unsigned int len, i;
1078 char *primtype;
1079
1080 switch ((data[0] >> 18) & 0xf) {
1081 case 0x0: primtype = "TRILIST"; break;
1082 case 0x1: primtype = "TRISTRIP"; break;
1083 case 0x2: primtype = "TRISTRIP_REVERSE"; break;
1084 case 0x3: primtype = "TRIFAN"; break;
1085 case 0x4: primtype = "POLYGON"; break;
1086 case 0x5: primtype = "LINELIST"; break;
1087 case 0x6: primtype = "LINESTRIP"; break;
1088 case 0x7: primtype = "RECTLIST"; break;
1089 case 0x8: primtype = "POINTLIST"; break;
1090 case 0x9: primtype = "DIB"; break;
1091 case 0xa: primtype = "CLEAR_RECT"; break;
1092 default: primtype = "unknown"; break;
1093 }
1094
1095 /* XXX: 3DPRIM_DIB not supported */
1096 if (immediate) {
1097 len = (data[0] & 0x0003ffff) + 2;
1098 instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype);
1099 if (count < len)
1100 BUFFER_FAIL(count, len, "3DPRIMITIVE inline");
1101 if (!saved_s2_set || !saved_s4_set) {
1102 fprintf(out, "unknown vertex format\n");
1103 for (i = 1; i < len; i++) {
1104 instr_out(data, hw_offset, i,
1105 " vertex data (%f float)\n",
1106 int_as_float(data[i]));
1107 }
1108 } else {
1109 unsigned int vertex = 0;
1110 for (i = 1; i < len;) {
1111 unsigned int tc;
1112
1113 #define VERTEX_OUT(fmt, ...) do { \
1114 if (i < len) \
1115 instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \
1116 else \
1117 fprintf(out, " missing data in V%d\n", vertex); \
1118 i++; \
1119 } while (0)
1120
1121 VERTEX_OUT("X = %f", int_as_float(data[i]));
1122 VERTEX_OUT("Y = %f", int_as_float(data[i]));
1123 switch (saved_s4 >> 6 & 0x7) {
1124 case 0x1:
1125 VERTEX_OUT("Z = %f", int_as_float(data[i]));
1126 break;
1127 case 0x2:
1128 VERTEX_OUT("Z = %f", int_as_float(data[i]));
1129 VERTEX_OUT("W = %f", int_as_float(data[i]));
1130 break;
1131 case 0x3:
1132 break;
1133 case 0x4:
1134 VERTEX_OUT("W = %f", int_as_float(data[i]));
1135 break;
1136 default:
1137 fprintf(out, "bad S4 position mask\n");
1138 }
1139
1140 if (saved_s4 & (1 << 10)) {
1141 VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, "
1142 "B=0x%02x)",
1143 data[i] >> 24,
1144 (data[i] >> 16) & 0xff,
1145 (data[i] >> 8) & 0xff,
1146 data[i] & 0xff);
1147 }
1148 if (saved_s4 & (1 << 11)) {
1149 VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, "
1150 "B=0x%02x)",
1151 data[i] >> 24,
1152 (data[i] >> 16) & 0xff,
1153 (data[i] >> 8) & 0xff,
1154 data[i] & 0xff);
1155 }
1156 if (saved_s4 & (1 << 12))
1157 VERTEX_OUT("width = 0x%08x)", data[i]);
1158
1159 for (tc = 0; tc <= 7; tc++) {
1160 switch ((saved_s2 >> (tc * 4)) & 0xf) {
1161 case 0x0:
1162 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
1163 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
1164 break;
1165 case 0x1:
1166 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
1167 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
1168 VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
1169 break;
1170 case 0x2:
1171 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
1172 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
1173 VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
1174 VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i]));
1175 break;
1176 case 0x3:
1177 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
1178 break;
1179 case 0x4:
1180 VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
1181 break;
1182 case 0x5:
1183 VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
1184 VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]);
1185 break;
1186 case 0xf:
1187 break;
1188 default:
1189 fprintf(out, "bad S2.T%d format\n", tc);
1190 }
1191 }
1192 vertex++;
1193 }
1194 }
1195 } else {
1196 /* indirect vertices */
1197 len = data[0] & 0x0000ffff; /* index count */
1198 if (data[0] & (1 << 17)) {
1199 /* random vertex access */
1200 if (count < (len + 1) / 2 + 1) {
1201 BUFFER_FAIL(count, (len + 1) / 2 + 1,
1202 "3DPRIMITIVE random indirect");
1203 }
1204 instr_out(data, hw_offset, 0,
1205 "3DPRIMITIVE random indirect %s (%d)\n", primtype, len);
1206 if (len == 0) {
1207 /* vertex indices continue until 0xffff is found */
1208 for (i = 1; i < count; i++) {
1209 if ((data[i] & 0xffff) == 0xffff) {
1210 instr_out(data, hw_offset, i,
1211 " indices: (terminator)\n");
1212 return i;
1213 } else if ((data[i] >> 16) == 0xffff) {
1214 instr_out(data, hw_offset, i,
1215 " indices: 0x%04x, "
1216 "(terminator)\n",
1217 data[i] & 0xffff);
1218 return i;
1219 } else {
1220 instr_out(data, hw_offset, i,
1221 " indices: 0x%04x, 0x%04x\n",
1222 data[i] & 0xffff, data[i] >> 16);
1223 }
1224 }
1225 fprintf(out,
1226 "3DPRIMITIVE: no terminator found in index buffer\n");
1227 (*failures)++;
1228 return count;
1229 } else {
1230 /* fixed size vertex index buffer */
1231 for (i = 0; i < len; i += 2) {
1232 if (i * 2 == len - 1) {
1233 instr_out(data, hw_offset, i,
1234 " indices: 0x%04x\n",
1235 data[i] & 0xffff);
1236 } else {
1237 instr_out(data, hw_offset, i,
1238 " indices: 0x%04x, 0x%04x\n",
1239 data[i] & 0xffff, data[i] >> 16);
1240 }
1241 }
1242 }
1243 return (len + 1) / 2 + 1;
1244 } else {
1245 /* sequential vertex access */
1246 if (count < 2)
1247 BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect");
1248 instr_out(data, hw_offset, 0,
1249 "3DPRIMITIVE sequential indirect %s, %d starting from "
1250 "%d\n", primtype, len, data[1] & 0xffff);
1251 instr_out(data, hw_offset, 1, " start\n");
1252 return 2;
1253 }
1254 }
1255
1256 return len;
1257 }
1258
1259 static int
1260 decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
1261 {
1262 unsigned int opcode;
1263
1264 struct {
1265 uint32_t opcode;
1266 int min_len;
1267 int max_len;
1268 char *name;
1269 } opcodes_3d[] = {
1270 { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" },
1271 { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" },
1272 { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" },
1273 { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" },
1274 { 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
1275 { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" },
1276 { 0x0d, 1, 1, "3DSTATE_MODES_4" },
1277 { 0x0c, 1, 1, "3DSTATE_MODES_5" },
1278 { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
1279 };
1280
1281 switch ((data[0] & 0x1f000000) >> 24) {
1282 case 0x1f:
1283 return decode_3d_primitive(data, count, hw_offset, failures);
1284 case 0x1d:
1285 return decode_3d_1d(data, count, hw_offset, failures, 0);
1286 case 0x1c:
1287 return decode_3d_1c(data, count, hw_offset, failures);
1288 }
1289
1290 for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
1291 opcode++) {
1292 if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
1293 unsigned int len = 1, i;
1294
1295 instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
1296 if (opcodes_3d[opcode].max_len > 1) {
1297 len = (data[0] & 0xff) + 2;
1298 if (len < opcodes_3d[opcode].min_len ||
1299 len > opcodes_3d[opcode].max_len)
1300 {
1301 fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
1302 }
1303 }
1304
1305 for (i = 1; i < len; i++) {
1306 if (i >= count)
1307 BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
1308 instr_out(data, hw_offset, i, "dword %d\n", i);
1309 }
1310 return len;
1311 }
1312 }
1313
1314 instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
1315 (*failures)++;
1316 return 1;
1317 }
1318
1319 static const char *
1320 get_965_surfacetype(unsigned int surfacetype)
1321 {
1322 switch (surfacetype) {
1323 case 0: return "1D";
1324 case 1: return "2D";
1325 case 2: return "3D";
1326 case 3: return "CUBE";
1327 case 4: return "BUFFER";
1328 case 7: return "NULL";
1329 default: return "unknown";
1330 }
1331 }
1332
1333 static const char *
1334 get_965_depthformat(unsigned int depthformat)
1335 {
1336 switch (depthformat) {
1337 case 0: return "s8_z24float";
1338 case 1: return "z32float";
1339 case 2: return "z24s8";
1340 case 5: return "z16";
1341 default: return "unknown";
1342 }
1343 }
1344
1345 static const char *
1346 get_965_element_component(uint32_t data, int component)
1347 {
1348 uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7;
1349
1350 switch (component_control) {
1351 case 0:
1352 return "nostore";
1353 case 1:
1354 switch (component) {
1355 case 0: return "X";
1356 case 1: return "Y";
1357 case 2: return "Z";
1358 case 3: return "W";
1359 default: return "fail";
1360 }
1361 case 2:
1362 return "0.0";
1363 case 3:
1364 return "1.0";
1365 case 4:
1366 return "0x1";
1367 case 5:
1368 return "VID";
1369 default:
1370 return "fail";
1371 }
1372 }
1373
1374 static const char *
1375 get_965_prim_type(uint32_t data)
1376 {
1377 uint32_t primtype = (data >> 10) & 0x1f;
1378
1379 switch (primtype) {
1380 case 0x01: return "point list";
1381 case 0x02: return "line list";
1382 case 0x03: return "line strip";
1383 case 0x04: return "tri list";
1384 case 0x05: return "tri strip";
1385 case 0x06: return "tri fan";
1386 case 0x07: return "quad list";
1387 case 0x08: return "quad strip";
1388 case 0x09: return "line list adj";
1389 case 0x0a: return "line strip adj";
1390 case 0x0b: return "tri list adj";
1391 case 0x0c: return "tri strip adj";
1392 case 0x0d: return "tri strip reverse";
1393 case 0x0e: return "polygon";
1394 case 0x0f: return "rect list";
1395 case 0x10: return "line loop";
1396 case 0x11: return "point list bf";
1397 case 0x12: return "line strip cont";
1398 case 0x13: return "line strip bf";
1399 case 0x14: return "line strip cont bf";
1400 case 0x15: return "tri fan no stipple";
1401 default: return "fail";
1402 }
1403 }
1404
1405 static int
1406 decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
1407 {
1408 unsigned int opcode, len;
1409 int i;
1410
1411 struct {
1412 uint32_t opcode;
1413 int min_len;
1414 int max_len;
1415 char *name;
1416 } opcodes_3d[] = {
1417 { 0x6000, 3, 3, "URB_FENCE" },
1418 { 0x6001, 2, 2, "CS_URB_STATE" },
1419 { 0x6002, 2, 2, "CONSTANT_BUFFER" },
1420 { 0x6101, 6, 6, "STATE_BASE_ADDRESS" },
1421 { 0x6102, 2, 2 , "STATE_SIP" },
1422 { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" },
1423 { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" },
1424 { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" },
1425 { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" },
1426 { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" },
1427 { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" },
1428 { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" },
1429 { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" },
1430 { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" },
1431 { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" },
1432 { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" },
1433 { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" },
1434 { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" },
1435 { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" },
1436 { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" },
1437 { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" },
1438 { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" },
1439 { 0x7b00, 6, 6, "3DPRIMITIVE" },
1440 { 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" },
1441 { 0x7810, 6, 6, "3DSTATE_VS_STATE" },
1442 { 0x7811, 6, 6, "3DSTATE_GS_STATE" },
1443 { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" },
1444 { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" },
1445 { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" },
1446 };
1447
1448 len = (data[0] & 0x0000ffff) + 2;
1449
1450 switch ((data[0] & 0xffff0000) >> 16) {
1451 case 0x6101:
1452 if (len != 6)
1453 fprintf(out, "Bad count in STATE_BASE_ADDRESS\n");
1454 if (count < 6)
1455 BUFFER_FAIL(count, len, "STATE_BASE_ADDRESS");
1456
1457 instr_out(data, hw_offset, 0,
1458 "STATE_BASE_ADDRESS\n");
1459
1460 if (data[1] & 1) {
1461 instr_out(data, hw_offset, 1, "General state at 0x%08x\n",
1462 data[1] & ~1);
1463 } else
1464 instr_out(data, hw_offset, 1, "General state not updated\n");
1465
1466 if (data[2] & 1) {
1467 instr_out(data, hw_offset, 2, "Surface state at 0x%08x\n",
1468 data[2] & ~1);
1469 } else
1470 instr_out(data, hw_offset, 2, "Surface state not updated\n");
1471
1472 if (data[3] & 1) {
1473 instr_out(data, hw_offset, 3, "Indirect state at 0x%08x\n",
1474 data[3] & ~1);
1475 } else
1476 instr_out(data, hw_offset, 3, "Indirect state not updated\n");
1477
1478 if (data[4] & 1) {
1479 instr_out(data, hw_offset, 4, "General state upper bound 0x%08x\n",
1480 data[4] & ~1);
1481 } else
1482 instr_out(data, hw_offset, 4, "General state not updated\n");
1483
1484 if (data[5] & 1) {
1485 instr_out(data, hw_offset, 5, "Indirect state upper bound 0x%08x\n",
1486 data[5] & ~1);
1487 } else
1488 instr_out(data, hw_offset, 5, "Indirect state not updated\n");
1489
1490 return len;
1491 case 0x7800:
1492 if (len != 7)
1493 fprintf(out, "Bad count in 3DSTATE_PIPELINED_POINTERS\n");
1494 if (count < 7)
1495 BUFFER_FAIL(count, len, "3DSTATE_PIPELINED_POINTERS");
1496
1497 instr_out(data, hw_offset, 0,
1498 "3DSTATE_PIPELINED_POINTERS\n");
1499 instr_out(data, hw_offset, 1, "VS state\n");
1500 instr_out(data, hw_offset, 2, "GS state\n");
1501 instr_out(data, hw_offset, 3, "Clip state\n");
1502 instr_out(data, hw_offset, 4, "SF state\n");
1503 instr_out(data, hw_offset, 5, "WM state\n");
1504 instr_out(data, hw_offset, 6, "CC state\n");
1505 return len;
1506 case 0x7801:
1507 if (len != 6)
1508 fprintf(out, "Bad count in 3DSTATE_BINDING_TABLE_POINTERS\n");
1509 if (count < 6)
1510 BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS");
1511
1512 instr_out(data, hw_offset, 0,
1513 "3DSTATE_BINDING_TABLE_POINTERS\n");
1514 instr_out(data, hw_offset, 1, "VS binding table\n");
1515 instr_out(data, hw_offset, 2, "GS binding table\n");
1516 instr_out(data, hw_offset, 3, "Clip binding table\n");
1517 instr_out(data, hw_offset, 4, "SF binding table\n");
1518 instr_out(data, hw_offset, 5, "WM binding table\n");
1519
1520 return len;
1521
1522 case 0x7808:
1523 len = (data[0] & 0xff) + 2;
1524 if ((len - 1) % 4 != 0)
1525 fprintf(out, "Bad count in 3DSTATE_VERTEX_BUFFERS\n");
1526 if (count < len)
1527 BUFFER_FAIL(count, len, "3DSTATE_VERTEX_BUFFERS");
1528 instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_BUFFERS\n");
1529
1530 for (i = 1; i < len;) {
1531 instr_out(data, hw_offset, i, "buffer %d: %s, pitch %db\n",
1532 data[i] >> 27,
1533 data[i] & (1 << 26) ? "random" : "sequential",
1534 data[i] & 0x07ff);
1535 i++;
1536 instr_out(data, hw_offset, i++, "buffer address\n");
1537 instr_out(data, hw_offset, i++, "max index\n");
1538 instr_out(data, hw_offset, i++, "mbz\n");
1539 }
1540 return len;
1541
1542 case 0x7809:
1543 len = (data[0] & 0xff) + 2;
1544 if ((len + 1) % 2 != 0)
1545 fprintf(out, "Bad count in 3DSTATE_VERTEX_ELEMENTS\n");
1546 if (count < len)
1547 BUFFER_FAIL(count, len, "3DSTATE_VERTEX_ELEMENTS");
1548 instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_ELEMENTS\n");
1549
1550 for (i = 1; i < len;) {
1551 instr_out(data, hw_offset, i, "buffer %d: %svalid, type 0x%04x, "
1552 "src offset 0x%04x bytes\n",
1553 data[i] >> 27,
1554 data[i] & (1 << 26) ? "" : "in",
1555 (data[i] >> 16) & 0x1ff,
1556 data[i] & 0x07ff);
1557 i++;
1558 instr_out(data, hw_offset, i, "(%s, %s, %s, %s), "
1559 "dst offset 0x%02x bytes\n",
1560 get_965_element_component(data[i], 0),
1561 get_965_element_component(data[i], 1),
1562 get_965_element_component(data[i], 2),
1563 get_965_element_component(data[i], 3),
1564 (data[i] & 0xff) * 4);
1565 i++;
1566 }
1567 return len;
1568
1569 case 0x780a:
1570 len = (data[0] & 0xff) + 2;
1571 if (len != 3)
1572 fprintf(out, "Bad count in 3DSTATE_INDEX_BUFFER\n");
1573 if (count < len)
1574 BUFFER_FAIL(count, len, "3DSTATE_INDEX_BUFFER");
1575 instr_out(data, hw_offset, 0, "3DSTATE_INDEX_BUFFER\n");
1576 instr_out(data, hw_offset, 1, "beginning buffer address\n");
1577 instr_out(data, hw_offset, 2, "ending buffer address\n");
1578 return len;
1579
1580 case 0x7900:
1581 if (len != 4)
1582 fprintf(out, "Bad count in 3DSTATE_DRAWING_RECTANGLE\n");
1583 if (count < 4)
1584 BUFFER_FAIL(count, len, "3DSTATE_DRAWING_RECTANGLE");
1585
1586 instr_out(data, hw_offset, 0,
1587 "3DSTATE_DRAWING_RECTANGLE\n");
1588 instr_out(data, hw_offset, 1, "top left: %d,%d\n",
1589 data[1] & 0xffff,
1590 (data[1] >> 16) & 0xffff);
1591 instr_out(data, hw_offset, 2, "bottom right: %d,%d\n",
1592 data[2] & 0xffff,
1593 (data[2] >> 16) & 0xffff);
1594 instr_out(data, hw_offset, 3, "origin: %d,%d\n",
1595 (int)data[3] & 0xffff,
1596 ((int)data[3] >> 16) & 0xffff);
1597
1598 return len;
1599
1600 case 0x7905:
1601 if (len < 5 || len > 7)
1602 fprintf(out, "Bad count in 3DSTATE_DEPTH_BUFFER\n");
1603 if (count < len)
1604 BUFFER_FAIL(count, len, "3DSTATE_DEPTH_BUFFER");
1605
1606 instr_out(data, hw_offset, 0,
1607 "3DSTATE_DEPTH_BUFFER\n");
1608 instr_out(data, hw_offset, 1, "%s, %s, pitch = %d bytes, %stiled\n",
1609 get_965_surfacetype(data[1] >> 29),
1610 get_965_depthformat((data[1] >> 18) & 0x7),
1611 (data[1] & 0x0001ffff) + 1,
1612 data[1] & (1 << 27) ? "" : "not ");
1613 instr_out(data, hw_offset, 2, "depth offset\n");
1614 instr_out(data, hw_offset, 3, "%dx%d\n",
1615 ((data[3] & 0x0007ffc0) >> 6) + 1,
1616 ((data[3] & 0xfff80000) >> 19) + 1);
1617 instr_out(data, hw_offset, 4, "volume depth\n");
1618 if (len == 6)
1619 instr_out(data, hw_offset, 5, "\n");
1620 if (len == 7)
1621 instr_out(data, hw_offset, 6, "render target view extent\n");
1622
1623 return len;
1624
1625 case 0x7b00:
1626 len = (data[0] & 0xff) + 2;
1627 if (len != 6)
1628 fprintf(out, "Bad count in 3DPRIMITIVE\n");
1629 if (count < len)
1630 BUFFER_FAIL(count, len, "3DPRIMITIVE");
1631
1632 instr_out(data, hw_offset, 0,
1633 "3DPRIMITIVE: %s %s\n",
1634 get_965_prim_type(data[0]),
1635 (data[0] & (1 << 15)) ? "random" : "sequential");
1636 instr_out(data, hw_offset, 1, "vertex count\n");
1637 instr_out(data, hw_offset, 2, "start vertex\n");
1638 instr_out(data, hw_offset, 3, "instance count\n");
1639 instr_out(data, hw_offset, 4, "start instance\n");
1640 instr_out(data, hw_offset, 5, "index bias\n");
1641 return len;
1642 }
1643
1644 for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
1645 opcode++) {
1646 if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) {
1647 unsigned int i;
1648 len = 1;
1649
1650 instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
1651 if (opcodes_3d[opcode].max_len > 1) {
1652 len = (data[0] & 0xff) + 2;
1653 if (len < opcodes_3d[opcode].min_len ||
1654 len > opcodes_3d[opcode].max_len)
1655 {
1656 fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
1657 }
1658 }
1659
1660 for (i = 1; i < len; i++) {
1661 if (i >= count)
1662 BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
1663 instr_out(data, hw_offset, i, "dword %d\n", i);
1664 }
1665 return len;
1666 }
1667 }
1668
1669 instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
1670 (*failures)++;
1671 return 1;
1672 }
1673
1674 static int
1675 decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)
1676 {
1677 unsigned int opcode;
1678
1679 struct {
1680 uint32_t opcode;
1681 int min_len;
1682 int max_len;
1683 char *name;
1684 } opcodes_3d[] = {
1685 { 0x02, 1, 1, "3DSTATE_MODES_3" },
1686 { 0x03, 1, 1, "3DSTATE_ENABLES_1"},
1687 { 0x04, 1, 1, "3DSTATE_ENABLES_2"},
1688 { 0x05, 1, 1, "3DSTATE_VFT0"},
1689 { 0x06, 1, 1, "3DSTATE_AA"},
1690 { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
1691 { 0x08, 1, 1, "3DSTATE_MODES_1" },
1692 { 0x09, 1, 1, "3DSTATE_STENCIL_TEST" },
1693 { 0x0a, 1, 1, "3DSTATE_VFT1"},
1694 { 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" },
1695 { 0x0c, 1, 1, "3DSTATE_MODES_5" },
1696 { 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" },
1697 { 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" },
1698 { 0x0f, 1, 1, "3DSTATE_MODES_2" },
1699 { 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
1700 { 0x16, 1, 1, "3DSTATE_MODES_4" },
1701 };
1702
1703 switch ((data[0] & 0x1f000000) >> 24) {
1704 case 0x1f:
1705 return decode_3d_primitive(data, count, hw_offset, failures);
1706 case 0x1d:
1707 return decode_3d_1d(data, count, hw_offset, failures, 1);
1708 case 0x1c:
1709 return decode_3d_1c(data, count, hw_offset, failures);
1710 }
1711
1712 for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
1713 opcode++) {
1714 if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
1715 unsigned int len = 1, i;
1716
1717 instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
1718 if (opcodes_3d[opcode].max_len > 1) {
1719 len = (data[0] & 0xff) + 2;
1720 if (len < opcodes_3d[opcode].min_len ||
1721 len > opcodes_3d[opcode].max_len)
1722 {
1723 fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
1724 }
1725 }
1726
1727 for (i = 1; i < len; i++) {
1728 if (i >= count)
1729 BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
1730 instr_out(data, hw_offset, i, "dword %d\n", i);
1731 }
1732 return len;
1733 }
1734 }
1735
1736 instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
1737 (*failures)++;
1738 return 1;
1739 }
1740
1741 /**
1742 * Decodes an i830-i915 batch buffer, writing the output to stdout.
1743 *
1744 * \param data batch buffer contents
1745 * \param count number of DWORDs to decode in the batch buffer
1746 * \param hw_offset hardware address for the buffer
1747 */
1748 int
1749 intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)
1750 {
1751 int index = 0;
1752 int failures = 0;
1753
1754 out = stderr;
1755
1756 while (index < count) {
1757 switch ((data[index] & 0xe0000000) >> 29) {
1758 case 0x0:
1759 index += decode_mi(data + index, count - index,
1760 hw_offset + index * 4, &failures);
1761 break;
1762 case 0x2:
1763 index += decode_2d(data + index, count - index,
1764 hw_offset + index * 4, &failures);
1765 break;
1766 case 0x3:
1767 if (IS_965(devid)) {
1768 index += decode_3d_965(data + index, count - index,
1769 hw_offset + index * 4, &failures);
1770 } else if (IS_9XX(devid)) {
1771 index += decode_3d(data + index, count - index,
1772 hw_offset + index * 4, &failures);
1773 } else {
1774 index += decode_3d_i830(data + index, count - index,
1775 hw_offset + index * 4, &failures);
1776 }
1777 break;
1778 default:
1779 instr_out(data, hw_offset, index, "UNKNOWN\n");
1780 failures++;
1781 index++;
1782 break;
1783 }
1784 fflush(out);
1785 }
1786
1787 return failures;
1788 }
1789
1790 void intel_decode_context_reset(void)
1791 {
1792 saved_s2_set = 0;
1793 saved_s4_set = 1;
1794 }
1795