i965_drv_video: improved MV quality for VME
[platform/upstream/libva.git] / i965_drv_video / intel_batchbuffer_dump.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <string.h>
4 #include <inttypes.h>
5
6 #include "intel_driver.h"
7 #include "intel_batchbuffer_dump.h"
8
9 #define BUFFER_FAIL(_count, _len, _name) do {                   \
10     fprintf(gout, "Buffer size too small in %s (%d < %d)\n",    \
11             (_name), (_count), (_len));                         \
12     (*failures)++;                                              \
13     return count;                                               \
14 } while (0)
15
16 static FILE *gout;
17
18 static void
19 instr_out(unsigned int *data, unsigned int offset, unsigned int index, char *fmt, ...)
20 {
21     va_list va;
22
23     fprintf(gout, "0x%08x: 0x%08x:%s ", offset + index * 4, data[index],
24             index == 0 ? "" : "  ");
25     va_start(va, fmt);
26     vfprintf(gout, fmt, va);
27     va_end(va);
28 }
29
30
31 static int
32 dump_mi(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
33 {
34     unsigned int opcode;
35     int length, i;
36
37     struct {
38         unsigned int opcode;
39         int mask_length;
40         int min_len;
41         int max_len;
42         char *name;
43     } mi_commands[] = {
44         { 0x00, 0, 1, 1, "MI_NOOP" },
45         { 0x04, 0, 1, 1, "MI_FLUSH" },
46         { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" },
47         { 0x26, 0x3f, 4, 5, "MI_FLUSH_DW" },
48     };
49
50     opcode = ((data[0] & MASK_MI_OPCODE) >> SHIFT_MI_OPCODE);
51
52     for (i = 0; i < sizeof(mi_commands) / sizeof(mi_commands[0]); i++) {
53         if (opcode == mi_commands[i].opcode) {
54             int index;
55
56             length = 1;
57             instr_out(data, offset, 0, "%s\n", mi_commands[i].name);
58
59             if (mi_commands[i].max_len > 1) {
60                 length = (data[0] & mi_commands[i].mask_length) + 2;
61
62                 if (length < mi_commands[i].min_len ||
63                     length > mi_commands[i].max_len) {
64                     fprintf(gout, "Bad length (%d) in %s, [%d, %d]\n",
65                             length, mi_commands[i].name,
66                             mi_commands[i].min_len,
67                             mi_commands[i].max_len);
68                 }
69             }
70
71             for (index = 1; index < length; index++) {
72                 if (index >= count)
73                     BUFFER_FAIL(count, length, mi_commands[i].name);
74
75                 instr_out(data, offset, index, "dword %d\n", index);
76             }
77
78             return length;
79         }
80     }
81
82     instr_out(data, offset, 0, "UNKNOWN MI COMMAND\n");
83     (*failures)++;
84     return 1;
85 }
86
87 static int
88 dump_gfxpipe_3d(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
89 {
90     instr_out(data, offset, 0, "UNKNOWN 3D COMMAND\n");
91     (*failures)++;
92
93     return 1;
94 }
95
96 static void
97 dump_avc_bsd_img_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
98 {
99     int img_struct = ((data[3] >> 8) & 0x3);
100
101     instr_out(data, offset, 1, "frame size: %d\n", (data[1] & 0xffff));
102     instr_out(data, offset, 2, "width: %d, height: %d\n", (data[2] & 0xff), (data[2] >> 16) & 0xff);
103     instr_out(data, offset, 3, 
104               "second_chroma_qp_offset: %d,"
105               "chroma_qp_offset: %d,"
106               "QM present flag: %d," 
107               "image struct: %s,"
108               "img_dec_fs_idc: %d,"
109               "\n",
110               (data[3] >> 24) & 0x1f,
111               (data[3] >> 16) & 0x1f,
112               (data[3] >> 10) & 0x1,
113               (img_struct == 0) ? "frame" : (img_struct == 2) ? "invalid" : (img_struct == 1) ? "top field" : "bottom field",
114               data[3] & 0xff);
115     instr_out(data, offset, 4,
116               "residual off: 0x%x,"
117               "16MV: %d,"
118               "chroma fmt: %d,"
119               "CABAC: %d,"
120               "non-ref: %d,"
121               "constrained intra: %d,"
122               "direct8x8: %d,"
123               "trans8x8: %d,"
124               "MB only: %d,"
125               "MBAFF: %d,"
126               "\n",
127               (data[4] >> 24) & 0xff,
128               (data[4] >> 12) & 0x1,
129               (data[4] >> 10) & 0x3,
130               (data[4] >> 7) & 0x1,
131               (data[4] >> 6) & 0x1,
132               (data[4] >> 5) & 0x1,
133               (data[4] >> 4) & 0x1,
134               (data[4] >> 3) & 0x1,
135               (data[4] >> 2) & 0x1,
136               (data[4] >> 1) & 0x1);
137     instr_out(data, offset, 5, "AVC-IT Command Header\n");
138 }
139
140 static void
141 dump_avc_bsd_qm_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
142 {
143     unsigned int length = ((data[0] & MASK_GFXPIPE_LENGTH) >> SHIFT_GFXPIPE_LENGTH) + 2;
144     int i;
145
146     instr_out(data, offset, 1, "user default: %02x, QM list present: %02x\n", 
147               (data[1] >> 8) & 0xff, data[1] & 0xff);
148
149     for (i = 2; i < length; i++) {
150         instr_out(data, offset, i, "dword %d\n", i);
151     }
152 }
153
154 static void
155 dump_avc_bsd_slice_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
156 {
157
158 }
159
160 static void
161 dump_avc_bsd_buf_base_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
162 {
163     int i;
164
165     instr_out(data, offset, 1, "BSD row store base address\n");
166     instr_out(data, offset, 2, "MPR row store base address\n");
167     instr_out(data, offset, 3, "AVC-IT command buffer base address\n");
168     instr_out(data, offset, 4, "AVC-IT data buffer: 0x%08x, write offset: 0x%x\n", 
169               data[4] & 0xFFFFF000, data[4] & 0xFC0);
170     instr_out(data, offset, 5, "ILDB data buffer\n");
171
172     for (i = 6; i < 38; i++) {
173         instr_out(data, offset, i, "Direct MV read base address for reference frame %d\n", i - 6);
174     }
175
176     instr_out(data, offset, 38, "direct mv wr0 top\n");
177     instr_out(data, offset, 39, "direct mv wr0 bottom\n");
178
179     for (i = 40; i < 74; i++) {
180         instr_out(data, offset, i, "POC List %d\n", i - 40);
181     }
182 }
183
184 static void
185 dump_bsd_ind_obj_base_addr(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
186 {
187     instr_out(data, offset, 1, "AVC indirect object base address\n");
188     instr_out(data, offset, 2, "AVC Indirect Object Access Upper Bound\n");
189 }
190
191 static void 
192 dump_ironlake_avc_bsd_object(unsigned int *data, unsigned int offset, int *failures)
193 {
194     int slice_type = data[3] & 0xf;
195     int i, is_phantom = ((data[1] & 0x3fffff) == 0);
196
197     if (!is_phantom) {
198         instr_out(data, offset, 1, "Encrypted: %d, bitsteam length: %d\n", data[1] >> 31, data[1] & 0x3fffff);
199         instr_out(data, offset, 2, "Indirect Data Start Address: %d\n", data[2] & 0x1fffffff);
200         instr_out(data, offset, 3, "%s Slice\n", slice_type == 0 ? "P" : slice_type == 1 ? "B" : "I");
201         instr_out(data, offset, 4, 
202                   "Num_Ref_Idx_L1: %d,"
203                   "Num_Ref_Idx_L0: %d,"
204                   "Log2WeightDenomChroma: %d,"
205                   "Log2WeightDenomLuma: %d"
206                   "\n",
207                   (data[4] >> 24) & 0x3f,
208                   (data[4] >> 16) & 0x3f,
209                   (data[4] >> 8) & 0x3,
210                   (data[4] >> 0) & 0x3);
211         instr_out(data, offset, 5,
212                   "WeightedPredIdc: %d,"
213                   "DirectPredType: %d,"
214                   "DisableDeblockingFilter: %d,"
215                   "CabacInitIdc: %d,"
216                   "SliceQp: %d,"
217                   "SliceBetaOffsetDiv2: %d,"
218                   "SliceAlphaC0OffsetDiv2: %d"
219                   "\n",
220                   (data[5] >> 30) & 0x3,
221                   (data[5] >> 29) & 0x1,
222                   (data[5] >> 27) & 0x3,
223                   (data[5] >> 24) & 0x3,
224                   (data[5] >> 16) & 0x3f,
225                   (data[5] >> 8) & 0xf,
226                   (data[5] >> 0) & 0xf);
227         instr_out(data, offset, 6,
228                   "Slice_MB_Start_Vert_Pos: %d,"
229                   "Slice_MB_Start_Hor_Pos: %d,"
230                   "Slice_Start_Mb_Num: %d"
231                   "\n",
232                   (data[6] >> 24) & 0xff,
233                   (data[6] >> 16) & 0xff,
234                   (data[6] >> 0) & 0x7fff);
235         instr_out(data, offset, 7,
236                   "Fix_Prev_Mb_Skipped: %d,"
237                   "First_MB_Bit_Offset: %d"
238                   "\n",
239                   (data[7] >> 7) & 0x1,
240                   (data[7] >> 0) & 0x7);
241
242         for (i = 8; i < 16; i++)
243             instr_out(data, offset, i, "dword %d\n", i);
244     } else {
245         instr_out(data, offset, 1, "phantom slice\n");
246
247         for (i = 2; i < 6; i++)
248             instr_out(data, offset, i, "dword %d\n", i);
249
250         instr_out(data, offset, 6,
251                   "Slice_Start_Mb_Num: %d"
252                   "\n",
253                   (data[6] >> 0) & 0x7fff);
254
255         for (i = 7; i < 16; i++)
256             instr_out(data, offset, i, "dword %d\n", i);
257
258     }
259 }
260
261 static void 
262 dump_g4x_avc_bsd_object(unsigned int *data, unsigned int offset, int *failures)
263 {
264
265 }
266
267 static void 
268 dump_avc_bsd_object(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
269 {
270     if (IS_IRONLAKE(device))
271         dump_ironlake_avc_bsd_object(data, offset, failures);
272     else
273         dump_g4x_avc_bsd_object(data, offset, failures);
274 }
275
276 static int
277 dump_bsd_avc(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
278 {
279     unsigned int subopcode;
280     int length, i;
281
282     struct {
283         unsigned int subopcode;
284         int min_len;
285         int max_len;
286         char *name;
287         void (*detail)(unsigned int *data, unsigned int offset, unsigned int device, int  *failures);
288     } avc_commands[] = {
289         { 0x00, 0x06, 0x06, "AVC_BSD_IMG_STATE", dump_avc_bsd_img_state },
290         { 0x01, 0x02, 0x3a, "AVC_BSD_QM_STATE", dump_avc_bsd_qm_state },
291         { 0x02, 0x02, 0xd2, "AVC_BSD_SLICE_STATE", NULL },
292         { 0x03, 0x4a, 0x4a, "AVC_BSD_BUF_BASE_STATE", dump_avc_bsd_buf_base_state },
293         { 0x04, 0x03, 0x03, "BSD_IND_OBJ_BASE_ADDR", dump_bsd_ind_obj_base_addr },
294         { 0x08, 0x08, 0x10, "AVC_BSD_OBJECT", dump_avc_bsd_object },
295     };
296
297     subopcode = ((data[0] & MASK_GFXPIPE_SUBOPCODE) >> SHIFT_GFXPIPE_SUBOPCODE);
298
299     for (i = 0; i < sizeof(avc_commands) / sizeof(avc_commands[0]); i++) {
300         if (subopcode == avc_commands[i].subopcode) {
301             unsigned int index;
302
303             length = (data[0] & MASK_GFXPIPE_LENGTH) >> SHIFT_GFXPIPE_LENGTH;
304             length += 2;
305             instr_out(data, offset, 0, "%s\n", avc_commands[i].name);
306
307             if (length < avc_commands[i].min_len || 
308                 length > avc_commands[i].max_len) {
309                 fprintf(gout, "Bad length(%d) in %s [%d, %d]\n", 
310                         length, avc_commands[i].name,
311                         avc_commands[i].min_len,
312                         avc_commands[i].max_len);
313             }
314
315             if (length - 1 >= count)
316                 BUFFER_FAIL(count, length, avc_commands[i].name);
317
318             if (avc_commands[i].detail)
319                 avc_commands[i].detail(data, offset, device, failures);
320             else {
321                 for (index = 1; index < length; index++)
322                     instr_out(data, offset, index, "dword %d\n", index);
323             }
324
325             return length;
326         }
327     }
328
329     instr_out(data, offset, 0, "UNKNOWN AVC COMMAND\n");
330     (*failures)++;
331     return 1;
332 }
333
334 static int
335 dump_gfxpipe_bsd(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
336 {
337     int length;
338
339     switch ((data[0] & MASK_GFXPIPE_OPCODE) >> SHIFT_GFXPIPE_OPCODE) {
340     case OPCODE_BSD_AVC:
341         length = dump_bsd_avc(data, offset, count, device, failures);
342         break;
343
344     default:
345         length = 1;
346         (*failures)++;
347         instr_out(data, offset, 0, "UNKNOWN BSD OPCODE\n");
348         break;
349     }
350
351     return length;
352 }
353
354 static void
355 dump_mfx_mode_select(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
356 {
357     instr_out(data, offset, 1, 
358               "decoder mode: %d(%s),"
359               "post deblocking output enable %d,"
360               "pre deblocking output enable %d,"
361               "codec select: %d(%s),"
362               "standard select: %d(%s)"
363               "\n",
364               (data[1] >> 16) & 0x1, ((data[1] >> 16) & 0x1) ? "IT" : "VLD",
365               (data[1] >> 9) & 0x1,
366               (data[1] >> 8) & 0x1,
367               (data[1] >> 4) & 0x1, ((data[1] >> 4) & 0x1) ? "Encode" : "Decode",
368               (data[1] >> 0) & 0x3, ((data[1] >> 0) & 0x3) == 0 ? "MPEG2" :
369               ((data[1] >> 0) & 0x3) == 1 ? "VC1" :
370               ((data[1] >> 0) & 0x3) == 2 ? "AVC" : "Reserved");
371     instr_out(data, offset, 2, "dword 02\n");
372     instr_out(data, offset, 3, "dword 03\n");
373 }
374
375 static void
376 dump_mfx_surface_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
377 {
378     instr_out(data, offset, 1, "dword 01\n");
379     instr_out(data, offset, 2, "dword 02\n");
380     instr_out(data, offset, 3, "dword 03\n");
381     instr_out(data, offset, 4, "dword 04\n");
382     instr_out(data, offset, 5, "dword 05\n");
383 }
384
385 static void
386 dump_mfx_pipe_buf_addr_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
387 {
388     instr_out(data, offset, 1, "dword 01\n");
389     instr_out(data, offset, 2, "dword 02\n");
390     instr_out(data, offset, 3, "dword 03\n");
391     instr_out(data, offset, 4, "dword 04\n");
392     instr_out(data, offset, 5, "dword 05\n");
393     instr_out(data, offset, 6, "dword 06\n");
394     instr_out(data, offset, 7, "dword 07\n");
395     instr_out(data, offset, 8, "dword 08\n");
396     instr_out(data, offset, 9, "dword 09\n");
397     instr_out(data, offset, 10, "dword 10\n");
398     instr_out(data, offset, 11, "dword 11\n");
399     instr_out(data, offset, 12, "dword 12\n");
400     instr_out(data, offset, 13, "dword 13\n");
401     instr_out(data, offset, 14, "dword 14\n");
402     instr_out(data, offset, 15, "dword 15\n");
403     instr_out(data, offset, 16, "dword 16\n");
404     instr_out(data, offset, 17, "dword 17\n");
405     instr_out(data, offset, 18, "dword 18\n");
406     instr_out(data, offset, 19, "dword 19\n");
407     instr_out(data, offset, 20, "dword 20\n");
408     instr_out(data, offset, 21, "dword 21\n");
409     instr_out(data, offset, 22, "dword 22\n");
410     instr_out(data, offset, 24, "dword 23\n");
411 }
412
413 static void
414 dump_mfx_ind_obj_base_addr_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
415 {
416     instr_out(data, offset, 1, "dword 01\n");
417     instr_out(data, offset, 2, "dword 02\n");
418     instr_out(data, offset, 3, "dword 03\n");
419     instr_out(data, offset, 4, "dword 04\n");
420     instr_out(data, offset, 5, "dword 05\n");
421     instr_out(data, offset, 6, "dword 06\n");
422     instr_out(data, offset, 7, "dword 07\n");
423     instr_out(data, offset, 8, "dword 08\n");
424     instr_out(data, offset, 9, "dword 09\n");
425     instr_out(data, offset, 10, "dword 10\n");
426 }
427
428 static void
429 dump_mfx_bsp_buf_base_addr_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
430 {
431     instr_out(data, offset, 1, "dword 01\n");
432     instr_out(data, offset, 2, "dword 02\n");
433     instr_out(data, offset, 3, "dword 03\n");
434 }
435
436 static void
437 dump_mfx_aes_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
438 {
439     instr_out(data, offset, 1, "dword 01\n");
440     instr_out(data, offset, 2, "dword 02\n");
441     instr_out(data, offset, 3, "dword 03\n");
442     instr_out(data, offset, 4, "dword 04\n");
443     instr_out(data, offset, 5, "dword 05\n");
444     instr_out(data, offset, 6, "dword 06\n");
445 }
446
447 static void
448 dump_mfx_state_pointer(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
449 {
450     instr_out(data, offset, 1, "dword 01\n");
451 }
452
453 static int
454 dump_mfx_common(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
455 {
456     unsigned int subopcode;
457     int length, i;
458
459     struct {
460         unsigned int subopcode;
461         int min_len;
462         int max_len;
463         char *name;
464         void (*detail)(unsigned int *data, unsigned int offset, unsigned int device, int  *failures);
465     } mfx_common_commands[] = {
466         { SUBOPCODE_MFX(0, 0), 0x04, 0x04, "MFX_PIPE_MODE_SELECT", dump_mfx_mode_select },
467         { SUBOPCODE_MFX(0, 1), 0x06, 0x06, "MFX_SURFACE_STATE", dump_mfx_surface_state },
468         { SUBOPCODE_MFX(0, 2), 0x18, 0x18, "MFX_PIPE_BUF_ADDR_STATE", dump_mfx_pipe_buf_addr_state },
469         { SUBOPCODE_MFX(0, 3), 0x0b, 0x0b, "MFX_IND_OBJ_BASE_ADDR_STATE", dump_mfx_ind_obj_base_addr_state },
470         { SUBOPCODE_MFX(0, 4), 0x04, 0x04, "MFX_BSP_BUF_BASE_ADDR_STATE", dump_mfx_bsp_buf_base_addr_state },
471         { SUBOPCODE_MFX(0, 5), 0x07, 0x07, "MFX_AES_STATE", dump_mfx_aes_state },
472         { SUBOPCODE_MFX(0, 6), 0x00, 0x00, "MFX_STATE_POINTER", dump_mfx_state_pointer },
473     };
474
475     subopcode = ((data[0] & MASK_GFXPIPE_SUBOPCODE) >> SHIFT_GFXPIPE_SUBOPCODE);
476
477     for (i = 0; i < ARRAY_ELEMS(mfx_common_commands); i++) {
478         if (subopcode == mfx_common_commands[i].subopcode) {
479             unsigned int index;
480
481             length = (data[0] & MASK_GFXPIPE_LENGTH) >> SHIFT_GFXPIPE_LENGTH;
482             length += 2;
483             instr_out(data, offset, 0, "%s\n", mfx_common_commands[i].name);
484
485             if (length < mfx_common_commands[i].min_len || 
486                 length > mfx_common_commands[i].max_len) {
487                 fprintf(gout, "Bad length(%d) in %s [%d, %d]\n", 
488                         length, mfx_common_commands[i].name,
489                         mfx_common_commands[i].min_len,
490                         mfx_common_commands[i].max_len);
491             }
492
493             if (length - 1 >= count)
494                 BUFFER_FAIL(count, length, mfx_common_commands[i].name);
495
496             if (mfx_common_commands[i].detail)
497                 mfx_common_commands[i].detail(data, offset, device, failures);
498             else {
499                 for (index = 1; index < length; index++)
500                     instr_out(data, offset, index, "dword %d\n", index);
501             }
502
503             return length;
504         }
505     }
506
507     instr_out(data, offset, 0, "UNKNOWN MFX COMMON COMMAND\n");
508     (*failures)++;
509     return 1;
510 }
511
512 static void
513 dump_mfx_avc_img_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
514 {
515     instr_out(data, offset, 1, "dword 01\n");
516     instr_out(data, offset, 2, "dword 02\n");
517     instr_out(data, offset, 3, "dword 03\n");
518     instr_out(data, offset, 4, "dword 04\n");
519     instr_out(data, offset, 5, "dword 05\n");
520     instr_out(data, offset, 6, "dword 06\n");
521     instr_out(data, offset, 7, "dword 07\n");
522     instr_out(data, offset, 8, "dword 08\n");
523     instr_out(data, offset, 9, "dword 09\n");
524     instr_out(data, offset, 10, "dword 10\n");
525     instr_out(data, offset, 11, "dword 11\n");
526     instr_out(data, offset, 12, "dword 12\n");
527 }
528
529 static void
530 dump_mfx_avc_qm_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
531 {
532     unsigned int length = ((data[0] & MASK_GFXPIPE_LENGTH) >> SHIFT_GFXPIPE_LENGTH) + 2;
533     int i;
534
535     instr_out(data, offset, 1, "user default: %02x, QM list present: %02x\n", 
536               (data[1] >> 8) & 0xff, data[1] & 0xff);
537
538     for (i = 2; i < length; i++) {
539         instr_out(data, offset, i, "dword %d\n", i);
540     }
541 }
542
543 static void
544 dump_mfx_avc_directmode_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
545 {
546     int i;
547
548     for (i = 1; i < 33; i++) {
549         instr_out(data, offset, i, "Direct MV Buffer Base Address for Picture %d\n", i - 1);
550     }
551
552     for (i = 33; i < 35; i++) {
553         instr_out(data, offset, i, "Direct MV Buffer Base Address for Current Decoding Frame/Field\n");
554     }
555
556     for (i = 35; i < 69; i++) {
557         instr_out(data, offset, i, "POC List\n");
558     }
559 }
560
561 static void
562 dump_mfx_avc_slice_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
563 {
564     instr_out(data, offset, 1, "dword 01\n");
565     instr_out(data, offset, 2, "dword 02\n");
566     instr_out(data, offset, 3, "dword 03\n");
567     instr_out(data, offset, 4, "dword 04\n");
568     instr_out(data, offset, 5, "dword 05\n");
569     instr_out(data, offset, 6, "dword 06\n");
570     instr_out(data, offset, 7, "dword 07\n");
571     instr_out(data, offset, 8, "dword 08\n");
572     instr_out(data, offset, 9, "dword 09\n");
573 }
574
575 static void
576 dump_mfx_avc_ref_idx_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
577 {
578     instr_out(data, offset, 1, "dword 01\n");
579     instr_out(data, offset, 2, "dword 02\n");
580     instr_out(data, offset, 3, "dword 03\n");
581     instr_out(data, offset, 4, "dword 04\n");
582     instr_out(data, offset, 5, "dword 05\n");
583     instr_out(data, offset, 6, "dword 06\n");
584     instr_out(data, offset, 7, "dword 07\n");
585     instr_out(data, offset, 8, "dword 08\n");
586     instr_out(data, offset, 9, "dword 09\n");
587 }
588
589 static void
590 dump_mfx_avc_weightoffset_state(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
591 {
592     int i;
593
594     instr_out(data, offset, 1, 
595               "Weight and Offset L%d table\n",
596               (data[1] >> 0) & 0x1);
597
598     for (i = 2; i < 31; i++) {
599         instr_out(data, offset, i, "dword %d\n", i);
600     }
601 }
602
603 static void
604 dump_mfd_bsd_object(unsigned int *data, unsigned int offset, unsigned int device, int *failures)
605 {
606     int is_phantom_slice = ((data[1] & 0x3fffff) == 0);
607
608     if (is_phantom_slice) {
609         instr_out(data, offset, 1, "phantom slice\n");
610         instr_out(data, offset, 2, "dword 02\n");
611         instr_out(data, offset, 3, "dword 03\n");
612         instr_out(data, offset, 4, "dword 04\n");
613         instr_out(data, offset, 5, "dword 05\n");
614     } else {
615         instr_out(data, offset, 1, "Indirect BSD Data Length: %d\n", data[1] & 0x3fffff);
616         instr_out(data, offset, 2, "Indirect BSD Data Start Address: 0x%08x\n", data[2] & 0x1fffffff);
617         instr_out(data, offset, 3, "dword 03\n");
618         instr_out(data, offset, 4,
619                   "First_MB_Byte_Offset of Slice Data from Slice Header: 0x%08x,"
620                   "slice header skip mode: %d"
621                   "\n",
622                   (data[4] >> 16),
623                   (data[4] >> 6) & 0x1);
624         instr_out(data, offset, 5, "dword 05\n");
625     }
626 }
627
628 static int
629 dump_mfx_avc(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
630 {
631     unsigned int subopcode;
632     int length, i;
633
634     struct {
635         unsigned int subopcode;
636         int min_len;
637         int max_len;
638         char *name;
639         void (*detail)(unsigned int *data, unsigned int offset, unsigned int device, int  *failures);
640     } mfx_avc_commands[] = {
641         { SUBOPCODE_MFX(0, 0), 0x0d, 0x0d, "MFX_AVC_IMG_STATE", dump_mfx_avc_img_state },
642         { SUBOPCODE_MFX(0, 1), 0x02, 0x3a, "MFX_AVC_QM_STATE", dump_mfx_avc_qm_state },
643         { SUBOPCODE_MFX(0, 2), 0x45, 0x45, "MFX_AVC_DIRECTMODE_STATE", dump_mfx_avc_directmode_state },
644         { SUBOPCODE_MFX(0, 3), 0x0b, 0x0b, "MFX_AVC_SLICE_STATE", dump_mfx_avc_slice_state },
645         { SUBOPCODE_MFX(0, 4), 0x0a, 0x0a, "MFX_AVC_REF_IDX_STATE", dump_mfx_avc_ref_idx_state },
646         { SUBOPCODE_MFX(0, 5), 0x32, 0x32, "MFX_AVC_WEIGHTOFFSET_STATE", dump_mfx_avc_weightoffset_state },
647         { SUBOPCODE_MFX(1, 8), 0x06, 0x06, "MFD_AVC_BSD_OBJECT", dump_mfd_bsd_object },
648     };
649
650     subopcode = ((data[0] & MASK_GFXPIPE_SUBOPCODE) >> SHIFT_GFXPIPE_SUBOPCODE);
651
652     for (i = 0; i < ARRAY_ELEMS(mfx_avc_commands); i++) {
653         if (subopcode == mfx_avc_commands[i].subopcode) {
654             unsigned int index;
655
656             length = (data[0] & MASK_GFXPIPE_LENGTH) >> SHIFT_GFXPIPE_LENGTH;
657             length += 2;
658             instr_out(data, offset, 0, "%s\n", mfx_avc_commands[i].name);
659
660             if (length < mfx_avc_commands[i].min_len || 
661                 length > mfx_avc_commands[i].max_len) {
662                 fprintf(gout, "Bad length(%d) in %s [%d, %d]\n", 
663                         length, mfx_avc_commands[i].name,
664                         mfx_avc_commands[i].min_len,
665                         mfx_avc_commands[i].max_len);
666             }
667
668             if (length - 1 >= count)
669                 BUFFER_FAIL(count, length, mfx_avc_commands[i].name);
670
671             if (mfx_avc_commands[i].detail)
672                 mfx_avc_commands[i].detail(data, offset, device, failures);
673             else {
674                 for (index = 1; index < length; index++)
675                     instr_out(data, offset, index, "dword %d\n", index);
676             }
677
678             return length;
679         }
680     }
681
682     instr_out(data, offset, 0, "UNKNOWN MFX AVC COMMAND\n");
683     (*failures)++;
684     return 1;
685 }
686
687 static int
688 dump_gfxpipe_mfx(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
689 {
690     int length;
691
692     switch ((data[0] & MASK_GFXPIPE_OPCODE) >> SHIFT_GFXPIPE_OPCODE) {
693     case OPCODE_MFX_COMMON:
694         length = dump_mfx_common(data, offset, count, device, failures);
695         break;
696
697     case OPCODE_MFX_AVC:
698         length = dump_mfx_avc(data, offset, count, device, failures);
699         break;
700
701     default:
702         length = 1;
703         (*failures)++;
704         instr_out(data, offset, 0, "UNKNOWN MFX OPCODE\n");
705         break;
706     }
707
708     return length;
709 }
710
711 static int
712 dump_gfxpipe(unsigned int *data, unsigned int offset, int count, unsigned int device, int *failures)
713 {
714     int length;
715
716     switch ((data[0] & MASK_GFXPIPE_SUBTYPE) >> SHIFT_GFXPIPE_SUBTYPE) {
717     case GFXPIPE_3D:
718         length = dump_gfxpipe_3d(data, offset, count, device, failures);
719         break;
720
721     case GFXPIPE_BSD:
722         if (IS_GEN6(device))
723             length = dump_gfxpipe_mfx(data, offset, count, device, failures);
724         else
725             length = dump_gfxpipe_bsd(data, offset, count, device, failures);
726
727         break;
728
729     default:
730         length = 1;
731         (*failures)++;
732         instr_out(data, offset, 0, "UNKNOWN GFXPIPE COMMAND\n");
733         break;
734     }
735
736     return length;
737 }
738
739 int intel_batchbuffer_dump(unsigned int *data, unsigned int offset, int count, unsigned int device)
740 {
741     int index = 0;
742     int failures = 0;
743
744     gout = fopen("/tmp/bsd_command_dump.txt", "w+");
745
746     while (index < count) {
747         switch ((data[index] & MASK_CMD_TYPE) >> SHIFT_CMD_TYPE) {
748         case CMD_TYPE_MI:
749             index += dump_mi(data + index, offset + index * 4,
750                              count - index, device, &failures);
751             break;
752
753         case CMD_TYPE_GFXPIPE:
754             index += dump_gfxpipe(data + index, offset + index * 4,
755                                   count - index, device, &failures);
756             break;
757
758         default:
759             instr_out(data, offset, index, "UNKNOWN COMMAND\n");
760             failures++;
761             index++;
762             break;
763         }
764
765         fflush(gout);
766     }
767
768     fclose(gout);
769
770     return failures;
771 }