1 /**************************************************************************
2  *
3  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include "main/imports.h"
29 
30 #include "i915_reg.h"
31 #include "i915_context.h"
32 #include "i915_debug.h"
33 
34 static bool
debug(struct debug_stream * stream,const char * name,GLuint len)35 debug(struct debug_stream *stream, const char *name, GLuint len)
36 {
37    GLuint i;
38    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
39 
40    if (len == 0) {
41       printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]);
42       assert(0);
43       return false;
44    }
45 
46    if (stream->print_addresses)
47       printf("%08x:  ", stream->offset);
48 
49 
50    printf("%s (%d dwords):\n", name, len);
51    for (i = 0; i < len; i++)
52       printf("\t0x%08x\n",  ptr[i]);
53    printf("\n");
54 
55    stream->offset += len * sizeof(GLuint);
56 
57    return true;
58 }
59 
60 
get_prim_name(GLuint val)61 static const char *get_prim_name( GLuint val )
62 {
63    switch (val & PRIM3D_MASK) {
64    case PRIM3D_TRILIST: return "TRILIST"; break;
65    case PRIM3D_TRISTRIP: return "TRISTRIP"; break;
66    case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break;
67    case PRIM3D_TRIFAN: return "TRIFAN"; break;
68    case PRIM3D_POLY: return "POLY"; break;
69    case PRIM3D_LINELIST: return "LINELIST"; break;
70    case PRIM3D_LINESTRIP: return "LINESTRIP"; break;
71    case PRIM3D_RECTLIST: return "RECTLIST"; break;
72    case PRIM3D_POINTLIST: return "POINTLIST"; break;
73    case PRIM3D_DIB: return "DIB"; break;
74    case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break;
75    case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break;
76    default: return "????"; break;
77    }
78 }
79 
80 static bool
debug_prim(struct debug_stream * stream,const char * name,bool dump_floats,GLuint len)81 debug_prim(struct debug_stream *stream, const char *name,
82 	   bool dump_floats, GLuint len)
83 {
84    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
85    const char *prim = get_prim_name( ptr[0] );
86    GLuint i;
87 
88 
89 
90    printf("%s %s (%d dwords):\n", name, prim, len);
91    printf("\t0x%08x\n",  ptr[0]);
92    for (i = 1; i < len; i++) {
93       if (dump_floats)
94 	 printf("\t0x%08x // %f\n",  ptr[i], *(GLfloat *)&ptr[i]);
95       else
96 	 printf("\t0x%08x\n",  ptr[i]);
97    }
98 
99 
100    printf("\n");
101 
102    stream->offset += len * sizeof(GLuint);
103 
104    return true;
105 }
106 
107 
108 
109 
110 static bool
debug_program(struct debug_stream * stream,const char * name,GLuint len)111 debug_program(struct debug_stream *stream, const char *name, GLuint len)
112 {
113    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
114 
115    if (len == 0) {
116       printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]);
117       assert(0);
118       return false;
119    }
120 
121    if (stream->print_addresses)
122       printf("%08x:  ", stream->offset);
123 
124    printf("%s (%d dwords):\n", name, len);
125    i915_disassemble_program( ptr, len );
126 
127    stream->offset += len * sizeof(GLuint);
128    return true;
129 }
130 
131 
132 static bool
debug_chain(struct debug_stream * stream,const char * name,GLuint len)133 debug_chain(struct debug_stream *stream, const char *name, GLuint len)
134 {
135    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
136    GLuint old_offset = stream->offset + len * sizeof(GLuint);
137    GLuint i;
138 
139    printf("%s (%d dwords):\n", name, len);
140    for (i = 0; i < len; i++)
141       printf("\t0x%08x\n",  ptr[i]);
142 
143    stream->offset = ptr[1] & ~0x3;
144 
145    if (stream->offset < old_offset)
146       printf("\n... skipping backwards from 0x%x --> 0x%x ...\n\n",
147 		   old_offset, stream->offset );
148    else
149       printf("\n... skipping from 0x%x --> 0x%x ...\n\n",
150 		   old_offset, stream->offset );
151 
152 
153    return true;
154 }
155 
156 
157 static bool
debug_variable_length_prim(struct debug_stream * stream)158 debug_variable_length_prim(struct debug_stream *stream)
159 {
160    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
161    const char *prim = get_prim_name( ptr[0] );
162    GLuint i, len;
163 
164    GLushort *idx = (GLushort *)(ptr+1);
165    for (i = 0; idx[i] != 0xffff; i++)
166       ;
167 
168    len = 1+(i+2)/2;
169 
170    printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len);
171    for (i = 0; i < len; i++)
172       printf("\t0x%08x\n",  ptr[i]);
173    printf("\n");
174 
175    stream->offset += len * sizeof(GLuint);
176    return true;
177 }
178 
179 
180 #define BITS( dw, hi, lo, ... )				\
181 do {							\
182    unsigned himask = 0xffffffffU >> (31 - (hi));		\
183    printf("\t\t ");				\
184    printf(__VA_ARGS__);			\
185    printf(": 0x%x\n", ((dw) & himask) >> (lo));	\
186 } while (0)
187 
188 #define MBZ( dw, hi, lo) do {							\
189    unsigned x = (dw) >> (lo);				\
190    unsigned lomask = (1 << (lo)) - 1;			\
191    unsigned himask;					\
192    himask = (1UL << (hi)) - 1;				\
193    assert ((x & himask & ~lomask) == 0);	\
194 } while (0)
195 
196 #define FLAG( dw, bit, ... )			\
197 do {							\
198    if (((dw) >> (bit)) & 1) {				\
199       printf("\t\t ");				\
200       printf(__VA_ARGS__);			\
201       printf("\n");				\
202    }							\
203 } while (0)
204 
205 static bool
debug_load_immediate(struct debug_stream * stream,const char * name,GLuint len)206 debug_load_immediate(struct debug_stream *stream, const char *name, GLuint len)
207 {
208    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
209    GLuint bits = (ptr[0] >> 4) & 0xff;
210    GLuint j = 0;
211 
212    printf("%s (%d dwords, flags: %x):\n", name, len, bits);
213    printf("\t0x%08x\n",  ptr[j++]);
214 
215    if (bits & (1<<0)) {
216       printf("\t  LIS0: 0x%08x\n", ptr[j]);
217       printf("\t vb address: 0x%08x\n", (ptr[j] & ~0x3));
218       BITS(ptr[j], 0, 0, "vb invalidate disable");
219       j++;
220    }
221    if (bits & (1<<1)) {
222       printf("\t  LIS1: 0x%08x\n", ptr[j]);
223       BITS(ptr[j], 29, 24, "vb dword width");
224       BITS(ptr[j], 21, 16, "vb dword pitch");
225       BITS(ptr[j], 15, 0, "vb max index");
226       j++;
227    }
228    if (bits & (1<<2)) {
229       int i;
230       printf("\t  LIS2: 0x%08x\n", ptr[j]);
231       for (i = 0; i < 8; i++) {
232 	 unsigned tc = (ptr[j] >> (i * 4)) & 0xf;
233 	 if (tc != 0xf)
234 	    BITS(tc, 3, 0, "tex coord %d", i);
235       }
236       j++;
237    }
238    if (bits & (1<<3)) {
239       printf("\t  LIS3: 0x%08x\n", ptr[j]);
240       j++;
241    }
242    if (bits & (1<<4)) {
243       printf("\t  LIS4: 0x%08x\n", ptr[j]);
244       BITS(ptr[j], 31, 23, "point width");
245       BITS(ptr[j], 22, 19, "line width");
246       FLAG(ptr[j], 18, "alpha flatshade");
247       FLAG(ptr[j], 17, "fog flatshade");
248       FLAG(ptr[j], 16, "spec flatshade");
249       FLAG(ptr[j], 15, "rgb flatshade");
250       BITS(ptr[j], 14, 13, "cull mode");
251       FLAG(ptr[j], 12, "vfmt: point width");
252       FLAG(ptr[j], 11, "vfmt: specular/fog");
253       FLAG(ptr[j], 10, "vfmt: rgba");
254       FLAG(ptr[j], 9, "vfmt: depth offset");
255       BITS(ptr[j], 8, 6, "vfmt: position (2==xyzw)");
256       FLAG(ptr[j], 5, "force dflt diffuse");
257       FLAG(ptr[j], 4, "force dflt specular");
258       FLAG(ptr[j], 3, "local depth offset enable");
259       FLAG(ptr[j], 2, "vfmt: fp32 fog coord");
260       FLAG(ptr[j], 1, "sprite point");
261       FLAG(ptr[j], 0, "antialiasing");
262       j++;
263    }
264    if (bits & (1<<5)) {
265       printf("\t  LIS5: 0x%08x\n", ptr[j]);
266       BITS(ptr[j], 31, 28, "rgba write disables");
267       FLAG(ptr[j], 27,     "force dflt point width");
268       FLAG(ptr[j], 26,     "last pixel enable");
269       FLAG(ptr[j], 25,     "global z offset enable");
270       FLAG(ptr[j], 24,     "fog enable");
271       BITS(ptr[j], 23, 16, "stencil ref");
272       BITS(ptr[j], 15, 13, "stencil test");
273       BITS(ptr[j], 12, 10, "stencil fail op");
274       BITS(ptr[j], 9, 7,   "stencil pass z fail op");
275       BITS(ptr[j], 6, 4,   "stencil pass z pass op");
276       FLAG(ptr[j], 3,      "stencil write enable");
277       FLAG(ptr[j], 2,      "stencil test enable");
278       FLAG(ptr[j], 1,      "color dither enable");
279       FLAG(ptr[j], 0,      "logiop enable");
280       j++;
281    }
282    if (bits & (1<<6)) {
283       printf("\t  LIS6: 0x%08x\n", ptr[j]);
284       FLAG(ptr[j], 31,      "alpha test enable");
285       BITS(ptr[j], 30, 28,  "alpha func");
286       BITS(ptr[j], 27, 20,  "alpha ref");
287       FLAG(ptr[j], 19,      "depth test enable");
288       BITS(ptr[j], 18, 16,  "depth func");
289       FLAG(ptr[j], 15,      "blend enable");
290       BITS(ptr[j], 14, 12,  "blend func");
291       BITS(ptr[j], 11, 8,   "blend src factor");
292       BITS(ptr[j], 7,  4,   "blend dst factor");
293       FLAG(ptr[j], 3,       "depth write enable");
294       FLAG(ptr[j], 2,       "color write enable");
295       BITS(ptr[j], 1,  0,   "provoking vertex");
296       j++;
297    }
298 
299 
300    printf("\n");
301 
302    assert(j == len);
303 
304    stream->offset += len * sizeof(GLuint);
305 
306    return true;
307 }
308 
309 
310 
311 static bool
debug_load_indirect(struct debug_stream * stream,const char * name,GLuint len)312 debug_load_indirect(struct debug_stream *stream, const char *name, GLuint len)
313 {
314    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
315    GLuint bits = (ptr[0] >> 8) & 0x3f;
316    GLuint i, j = 0;
317 
318    printf("%s (%d dwords):\n", name, len);
319    printf("\t0x%08x\n",  ptr[j++]);
320 
321    for (i = 0; i < 6; i++) {
322       if (bits & (1<<i)) {
323 	 switch (1<<(8+i)) {
324 	 case LI0_STATE_STATIC_INDIRECT:
325 	    printf("        STATIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
326 	    printf("                0x%08x\n", ptr[j++]);
327 	    break;
328 	 case LI0_STATE_DYNAMIC_INDIRECT:
329 	    printf("       DYNAMIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
330 	    break;
331 	 case LI0_STATE_SAMPLER:
332 	    printf("       SAMPLER: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
333 	    printf("                0x%08x\n", ptr[j++]);
334 	    break;
335 	 case LI0_STATE_MAP:
336 	    printf("           MAP: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
337 	    printf("                0x%08x\n", ptr[j++]);
338 	    break;
339 	 case LI0_STATE_PROGRAM:
340 	    printf("       PROGRAM: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
341 	    printf("                0x%08x\n", ptr[j++]);
342 	    break;
343 	 case LI0_STATE_CONSTANTS:
344 	    printf("     CONSTANTS: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
345 	    printf("                0x%08x\n", ptr[j++]);
346 	    break;
347 	 default:
348 	    assert(0);
349 	    break;
350 	 }
351       }
352    }
353 
354    if (bits == 0) {
355       printf("\t  DUMMY: 0x%08x\n", ptr[j++]);
356    }
357 
358    printf("\n");
359 
360 
361    assert(j == len);
362 
363    stream->offset += len * sizeof(GLuint);
364 
365    return true;
366 }
367 
BR13(struct debug_stream * stream,GLuint val)368 static void BR13( struct debug_stream *stream,
369 		  GLuint val )
370 {
371    printf("\t0x%08x\n",  val);
372    FLAG(val, 30, "clipping enable");
373    BITS(val, 25, 24, "color depth (3==32bpp)");
374    BITS(val, 23, 16, "raster op");
375    BITS(val, 15, 0,  "dest pitch");
376 }
377 
378 
BR2223(struct debug_stream * stream,GLuint val22,GLuint val23)379 static void BR2223( struct debug_stream *stream,
380 		    GLuint val22, GLuint val23 )
381 {
382    union { GLuint val; short field[2]; } BR22, BR23;
383 
384    BR22.val = val22;
385    BR23.val = val23;
386 
387    printf("\t0x%08x\n",  val22);
388    BITS(val22, 31, 16, "dest y1");
389    BITS(val22, 15, 0,  "dest x1");
390 
391    printf("\t0x%08x\n",  val23);
392    BITS(val23, 31, 16, "dest y2");
393    BITS(val23, 15, 0,  "dest x2");
394 
395    /* The blit engine may produce unexpected results when these aren't met */
396    assert(BR22.field[0] < BR23.field[0]);
397    assert(BR22.field[1] < BR23.field[1]);
398 }
399 
BR09(struct debug_stream * stream,GLuint val)400 static void BR09( struct debug_stream *stream,
401 		  GLuint val )
402 {
403    printf("\t0x%08x -- dest address\n",  val);
404 }
405 
BR26(struct debug_stream * stream,GLuint val)406 static void BR26( struct debug_stream *stream,
407 		  GLuint val )
408 {
409    printf("\t0x%08x\n",  val);
410    BITS(val, 31, 16, "src y1");
411    BITS(val, 15, 0,  "src x1");
412 }
413 
BR11(struct debug_stream * stream,GLuint val)414 static void BR11( struct debug_stream *stream,
415 		  GLuint val )
416 {
417    printf("\t0x%08x\n",  val);
418    BITS(val, 15, 0,  "src pitch");
419 }
420 
BR12(struct debug_stream * stream,GLuint val)421 static void BR12( struct debug_stream *stream,
422 		  GLuint val )
423 {
424    printf("\t0x%08x -- src address\n",  val);
425 }
426 
BR16(struct debug_stream * stream,GLuint val)427 static void BR16( struct debug_stream *stream,
428 		  GLuint val )
429 {
430    printf("\t0x%08x -- color\n",  val);
431 }
432 
433 static bool
debug_copy_blit(struct debug_stream * stream,const char * name,GLuint len)434 debug_copy_blit(struct debug_stream *stream, const char *name, GLuint len)
435 {
436    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
437    int j = 0;
438 
439    printf("%s (%d dwords):\n", name, len);
440    printf("\t0x%08x\n",  ptr[j++]);
441 
442    BR13(stream, ptr[j++]);
443    BR2223(stream, ptr[j], ptr[j+1]);
444    j += 2;
445    BR09(stream, ptr[j++]);
446    BR26(stream, ptr[j++]);
447    BR11(stream, ptr[j++]);
448    BR12(stream, ptr[j++]);
449 
450    stream->offset += len * sizeof(GLuint);
451    assert(j == len);
452    return true;
453 }
454 
455 static bool
debug_color_blit(struct debug_stream * stream,const char * name,GLuint len)456 debug_color_blit(struct debug_stream *stream, const char *name, GLuint len)
457 {
458    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
459    int j = 0;
460 
461    printf("%s (%d dwords):\n", name, len);
462    printf("\t0x%08x\n",  ptr[j++]);
463 
464    BR13(stream, ptr[j++]);
465    BR2223(stream, ptr[j], ptr[j+1]);
466    j += 2;
467    BR09(stream, ptr[j++]);
468    BR16(stream, ptr[j++]);
469 
470    stream->offset += len * sizeof(GLuint);
471    assert(j == len);
472    return true;
473 }
474 
475 static bool
debug_modes4(struct debug_stream * stream,const char * name,GLuint len)476 debug_modes4(struct debug_stream *stream, const char *name, GLuint len)
477 {
478    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
479    int j = 0;
480 
481    printf("%s (%d dwords):\n", name, len);
482    printf("\t0x%08x\n",  ptr[j]);
483    BITS(ptr[j], 21, 18, "logicop func");
484    FLAG(ptr[j], 17, "stencil test mask modify-enable");
485    FLAG(ptr[j], 16, "stencil write mask modify-enable");
486    BITS(ptr[j], 15, 8, "stencil test mask");
487    BITS(ptr[j], 7, 0,  "stencil write mask");
488    j++;
489 
490    stream->offset += len * sizeof(GLuint);
491    assert(j == len);
492    return true;
493 }
494 
495 static bool
debug_map_state(struct debug_stream * stream,const char * name,GLuint len)496 debug_map_state(struct debug_stream *stream, const char *name, GLuint len)
497 {
498    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
499    int j = 0;
500 
501    printf("%s (%d dwords):\n", name, len);
502    printf("\t0x%08x\n",  ptr[j++]);
503 
504    {
505       printf("\t0x%08x\n",  ptr[j]);
506       BITS(ptr[j], 15, 0,   "map mask");
507       j++;
508    }
509 
510    while (j < len) {
511       {
512 	 printf("\t  TMn.0: 0x%08x\n", ptr[j]);
513 	 printf("\t map address: 0x%08x\n", (ptr[j] & ~0x3));
514 	 FLAG(ptr[j], 1, "vertical line stride");
515 	 FLAG(ptr[j], 0, "vertical line stride offset");
516 	 j++;
517       }
518 
519       {
520 	 printf("\t  TMn.1: 0x%08x\n", ptr[j]);
521 	 BITS(ptr[j], 31, 21, "height");
522 	 BITS(ptr[j], 20, 10, "width");
523 	 BITS(ptr[j], 9, 7, "surface format");
524 	 BITS(ptr[j], 6, 3, "texel format");
525 	 FLAG(ptr[j], 2, "use fence regs");
526 	 FLAG(ptr[j], 1, "tiled surface");
527 	 FLAG(ptr[j], 0, "tile walk ymajor");
528 	 j++;
529       }
530       {
531 	 printf("\t  TMn.2: 0x%08x\n", ptr[j]);
532 	 BITS(ptr[j], 31, 21, "dword pitch");
533 	 BITS(ptr[j], 20, 15, "cube face enables");
534 	 BITS(ptr[j], 14, 9, "max lod");
535 	 FLAG(ptr[j], 8,     "mip layout right");
536 	 BITS(ptr[j], 7, 0, "depth");
537 	 j++;
538       }
539    }
540 
541    stream->offset += len * sizeof(GLuint);
542    assert(j == len);
543    return true;
544 }
545 
546 static bool
debug_sampler_state(struct debug_stream * stream,const char * name,GLuint len)547 debug_sampler_state(struct debug_stream *stream, const char *name, GLuint len)
548 {
549    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
550    int j = 0;
551 
552    printf("%s (%d dwords):\n", name, len);
553    printf("\t0x%08x\n",  ptr[j++]);
554 
555    {
556       printf("\t0x%08x\n",  ptr[j]);
557       BITS(ptr[j], 15, 0,   "sampler mask");
558       j++;
559    }
560 
561    while (j < len) {
562       {
563 	 printf("\t  TSn.0: 0x%08x\n", ptr[j]);
564 	 FLAG(ptr[j], 31, "reverse gamma");
565 	 FLAG(ptr[j], 30, "planar to packed");
566 	 FLAG(ptr[j], 29, "yuv->rgb");
567 	 BITS(ptr[j], 28, 27, "chromakey index");
568 	 BITS(ptr[j], 26, 22, "base mip level");
569 	 BITS(ptr[j], 21, 20, "mip mode filter");
570 	 BITS(ptr[j], 19, 17, "mag mode filter");
571 	 BITS(ptr[j], 16, 14, "min mode filter");
572 	 BITS(ptr[j], 13, 5,  "lod bias (s4.4)");
573 	 FLAG(ptr[j], 4,      "shadow enable");
574 	 FLAG(ptr[j], 3,      "max-aniso-4");
575 	 BITS(ptr[j], 2, 0,   "shadow func");
576 	 j++;
577       }
578 
579       {
580 	 printf("\t  TSn.1: 0x%08x\n", ptr[j]);
581 	 BITS(ptr[j], 31, 24, "min lod");
582 	 MBZ( ptr[j], 23, 18 );
583 	 FLAG(ptr[j], 17,     "kill pixel enable");
584 	 FLAG(ptr[j], 16,     "keyed tex filter mode");
585 	 FLAG(ptr[j], 15,     "chromakey enable");
586 	 BITS(ptr[j], 14, 12, "tcx wrap mode");
587 	 BITS(ptr[j], 11, 9,  "tcy wrap mode");
588 	 BITS(ptr[j], 8,  6,  "tcz wrap mode");
589 	 FLAG(ptr[j], 5,      "normalized coords");
590 	 BITS(ptr[j], 4,  1,  "map (surface) index");
591 	 FLAG(ptr[j], 0,      "EAST deinterlacer enable");
592 	 j++;
593       }
594       {
595 	 printf("\t  TSn.2: 0x%08x  (default color)\n", ptr[j]);
596 	 j++;
597       }
598    }
599 
600    stream->offset += len * sizeof(GLuint);
601    assert(j == len);
602    return true;
603 }
604 
605 static bool
debug_dest_vars(struct debug_stream * stream,const char * name,GLuint len)606 debug_dest_vars(struct debug_stream *stream, const char *name, GLuint len)
607 {
608    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
609    int j = 0;
610 
611    printf("%s (%d dwords):\n", name, len);
612    printf("\t0x%08x\n",  ptr[j++]);
613 
614    {
615       printf("\t0x%08x\n",  ptr[j]);
616       FLAG(ptr[j], 31,     "early classic ztest");
617       FLAG(ptr[j], 30,     "opengl tex default color");
618       FLAG(ptr[j], 29,     "bypass iz");
619       FLAG(ptr[j], 28,     "lod preclamp");
620       BITS(ptr[j], 27, 26, "dither pattern");
621       FLAG(ptr[j], 25,     "linear gamma blend");
622       FLAG(ptr[j], 24,     "debug dither");
623       BITS(ptr[j], 23, 20, "dstorg x");
624       BITS(ptr[j], 19, 16, "dstorg y");
625       MBZ (ptr[j], 15, 15 );
626       BITS(ptr[j], 14, 12, "422 write select");
627       BITS(ptr[j], 11, 8,  "cbuf format");
628       BITS(ptr[j], 3, 2,   "zbuf format");
629       FLAG(ptr[j], 1,      "vert line stride");
630       FLAG(ptr[j], 1,      "vert line stride offset");
631       j++;
632    }
633 
634    stream->offset += len * sizeof(GLuint);
635    assert(j == len);
636    return true;
637 }
638 
639 static bool
debug_buf_info(struct debug_stream * stream,const char * name,GLuint len)640 debug_buf_info(struct debug_stream *stream, const char *name, GLuint len)
641 {
642    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
643    int j = 0;
644 
645    printf("%s (%d dwords):\n", name, len);
646    printf("\t0x%08x\n",  ptr[j++]);
647 
648    {
649       printf("\t0x%08x\n",  ptr[j]);
650       BITS(ptr[j], 28, 28, "aux buffer id");
651       BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)");
652       FLAG(ptr[j], 23,     "use fence regs");
653       FLAG(ptr[j], 22,     "tiled surface");
654       FLAG(ptr[j], 21,     "tile walk ymajor");
655       MBZ (ptr[j], 20, 14);
656       BITS(ptr[j], 13, 2,  "dword pitch");
657       MBZ (ptr[j], 2,  0);
658       j++;
659    }
660 
661    printf("\t0x%08x -- buffer base address\n",  ptr[j++]);
662 
663    stream->offset += len * sizeof(GLuint);
664    assert(j == len);
665    return true;
666 }
667 
668 static bool
i915_debug_packet(struct debug_stream * stream)669 i915_debug_packet(struct debug_stream *stream)
670 {
671    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
672    GLuint cmd = *ptr;
673 
674    switch (((cmd >> 29) & 0x7)) {
675    case 0x0:
676       switch ((cmd >> 23) & 0x3f) {
677       case 0x0:
678 	 return debug(stream, "MI_NOOP", 1);
679       case 0x3:
680 	 return debug(stream, "MI_WAIT_FOR_EVENT", 1);
681       case 0x4:
682 	 return debug(stream, "MI_FLUSH", 1);
683       case 0xA:
684 	 debug(stream, "MI_BATCH_BUFFER_END", 1);
685 	 return false;
686       case 0x22:
687 	 return debug(stream, "MI_LOAD_REGISTER_IMM", 3);
688       case 0x31:
689 	 return debug_chain(stream, "MI_BATCH_BUFFER_START", 2);
690       default:
691 	 break;
692       }
693       break;
694    case 0x1:
695       break;
696    case 0x2:
697       switch ((cmd >> 22) & 0xff) {
698       case 0x50:
699 	 return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2);
700       case 0x53:
701 	 return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2);
702       default:
703 	 return debug(stream, "blit command", (cmd & 0xff) + 2);
704       }
705       break;
706    case 0x3:
707       switch ((cmd >> 24) & 0x1f) {
708       case 0x6:
709 	 return debug(stream, "3DSTATE_ANTI_ALIASING", 1);
710       case 0x7:
711 	 return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1);
712       case 0x8:
713 	 return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2);
714       case 0x9:
715 	 return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1);
716       case 0xb:
717 	 return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1);
718       case 0xc:
719 	 return debug(stream, "3DSTATE_MODES5", 1);
720       case 0xd:
721 	 return debug_modes4(stream, "3DSTATE_MODES4", 1);
722       case 0x15:
723 	 return debug(stream, "3DSTATE_FOG_COLOR", 1);
724       case 0x16:
725 	 return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1);
726       case 0x1c:
727 	 /* 3DState16NP */
728 	 switch((cmd >> 19) & 0x1f) {
729 	 case 0x10:
730 	    return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1);
731 	 case 0x11:
732 	    return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1);
733 	 default:
734 	    break;
735 	 }
736 	 break;
737       case 0x1d:
738 	 /* 3DStateMW */
739 	 switch ((cmd >> 16) & 0xff) {
740 	 case 0x0:
741 	    return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2);
742 	 case 0x1:
743 	    return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2);
744 	 case 0x4:
745 	    return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2);
746 	 case 0x5:
747 	    return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2);
748 	 case 0x6:
749 	    return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2);
750 	 case 0x7:
751 	    return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2);
752 	 case 0x80:
753 	    return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2);
754 	 case 0x81:
755 	    return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2);
756 	 case 0x83:
757 	    return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2);
758 	 case 0x85:
759 	    return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2);
760 	 case 0x88:
761 	    return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2);
762 	 case 0x89:
763 	    return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2);
764 	 case 0x8e:
765 	    return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2);
766 	 case 0x97:
767 	    return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2);
768 	 case 0x98:
769 	    return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2);
770 	 case 0x99:
771 	    return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2);
772 	 case 0x9a:
773 	    return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2);
774 	 case 0x9c:
775 	    return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2);
776 	 default:
777 	    assert(0);
778 	    return 0;
779 	 }
780 	 break;
781       case 0x1e:
782 	 if (cmd & (1 << 23))
783 	    return debug(stream, "???", (cmd & 0xffff) + 1);
784 	 else
785 	    return debug(stream, "", 1);
786 	 break;
787       case 0x1f:
788 	 if ((cmd & (1 << 23)) == 0)
789 	    return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2);
790 	 else if (cmd & (1 << 17))
791 	 {
792 	    if ((cmd & 0xffff) == 0)
793 	       return debug_variable_length_prim(stream);
794 	    else
795 	       return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1);
796 	 }
797 	 else
798 	    return debug_prim(stream, "3DPRIM  (indirect sequential)", 0, 2);
799 	 break;
800       default:
801 	 return debug(stream, "", 0);
802       }
803       break;
804    default:
805       assert(0);
806       return 0;
807    }
808 
809    assert(0);
810    return 0;
811 }
812 
813 
814 
815 void
i915_dump_batchbuffer(GLuint * start,GLuint * end)816 i915_dump_batchbuffer( GLuint *start,
817 		       GLuint *end )
818 {
819    struct debug_stream stream;
820    GLuint bytes = (end - start) * 4;
821    bool done = false;
822 
823    printf("\n\nBATCH: (%d)\n", bytes / 4);
824 
825    stream.offset = 0;
826    stream.ptr = (char *)start;
827    stream.print_addresses = 0;
828 
829    while (!done &&
830 	  stream.offset < bytes &&
831 	  stream.offset >= 0)
832    {
833       if (!i915_debug_packet( &stream ))
834 	 break;
835 
836       assert(stream.offset <= bytes &&
837 	     stream.offset >= 0);
838    }
839 
840    printf("END-BATCH\n\n\n");
841 }
842 
843 
844