OSDN Git Service

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