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
34static bool
35debug(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
61static 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
80static bool
81debug_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
110static bool
111debug_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
132static bool
133debug_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
157static bool
158debug_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, ... )				\
181do {							\
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, ... )			\
197do {							\
198   if (((dw) >> (bit)) & 1) {				\
199      printf("\t\t ");				\
200      printf(__VA_ARGS__);			\
201      printf("\n");				\
202   }							\
203} while (0)
204
205static bool
206debug_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
311static bool
312debug_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
368static 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
379static 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
400static void BR09( struct debug_stream *stream,
401		  GLuint val )
402{
403   printf("\t0x%08x -- dest address\n",  val);
404}
405
406static 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
414static 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
421static void BR12( struct debug_stream *stream,
422		  GLuint val )
423{
424   printf("\t0x%08x -- src address\n",  val);
425}
426
427static void BR16( struct debug_stream *stream,
428		  GLuint val )
429{
430   printf("\t0x%08x -- color\n",  val);
431}
432
433static bool
434debug_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
455static bool
456debug_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
475static bool
476debug_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
495static bool
496debug_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
546static bool
547debug_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
605static bool
606debug_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
639static bool
640debug_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
668static bool
669i915_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
815void
816i915_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