1/**************************************************************************
2 *
3 * Copyright 2003 VMware, Inc.
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 VMWARE 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 "i915_debug.h"
29#include "util/log.h"
30#include "util/ralloc.h"
31#include "util/u_debug.h"
32#include "i915_batch.h"
33#include "i915_context.h"
34#include "i915_debug_private.h"
35#include "i915_reg.h"
36#include "i915_screen.h"
37
38static const struct debug_named_value i915_debug_options[] = {
39   {"blit", DBG_BLIT, "Print when using the 2d blitter"},
40   {"emit", DBG_EMIT, "State emit information"},
41   {"atoms", DBG_ATOMS, "Print dirty state atoms"},
42   {"flush", DBG_FLUSH, "Flushing information"},
43   {"texture", DBG_TEXTURE, "Texture information"},
44   {"constants", DBG_CONSTANTS, "Constant buffers"},
45   {"fs", DBG_FS, "Dump fragment shaders"},
46   {"vbuf", DBG_VBUF, "Use the WIP vbuf code path"},
47   DEBUG_NAMED_VALUE_END};
48
49unsigned i915_debug = 0;
50
51DEBUG_GET_ONCE_FLAGS_OPTION(i915_debug, "I915_DEBUG", i915_debug_options, 0)
52DEBUG_GET_ONCE_BOOL_OPTION(i915_no_tiling, "I915_NO_TILING", false)
53DEBUG_GET_ONCE_BOOL_OPTION(i915_lie, "I915_LIE", true)
54DEBUG_GET_ONCE_BOOL_OPTION(i915_use_blitter, "I915_USE_BLITTER", true)
55
56void
57i915_debug_init(struct i915_screen *is)
58{
59   i915_debug = debug_get_option_i915_debug();
60   is->debug.tiling = !debug_get_option_i915_no_tiling();
61   is->debug.lie = debug_get_option_i915_lie();
62   is->debug.use_blitter = debug_get_option_i915_use_blitter();
63}
64
65/***********************************************************************
66 * Batchbuffer dumping
67 */
68
69static bool
70debug(struct debug_stream *stream, const char *name, unsigned len)
71{
72   unsigned i;
73   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
74
75   if (len == 0) {
76      mesa_logi("Error - zero length packet (0x%08x)", stream->ptr[0]);
77      assert(0);
78      return false;
79   }
80
81   if (stream->print_addresses)
82      mesa_logi("%08x:  ", stream->offset);
83
84   mesa_logi("%s (%d dwords):", name, len);
85   for (i = 0; i < len; i++)
86      mesa_logi("\t0x%08x", ptr[i]);
87   mesa_logi("%s", "");
88
89   stream->offset += len * sizeof(unsigned);
90
91   return true;
92}
93
94static const char *
95get_prim_name(unsigned val)
96{
97   switch (val & PRIM3D_MASK) {
98   case PRIM3D_TRILIST:
99      return "TRILIST";
100      break;
101   case PRIM3D_TRISTRIP:
102      return "TRISTRIP";
103      break;
104   case PRIM3D_TRISTRIP_RVRSE:
105      return "TRISTRIP_RVRSE";
106      break;
107   case PRIM3D_TRIFAN:
108      return "TRIFAN";
109      break;
110   case PRIM3D_POLY:
111      return "POLY";
112      break;
113   case PRIM3D_LINELIST:
114      return "LINELIST";
115      break;
116   case PRIM3D_LINESTRIP:
117      return "LINESTRIP";
118      break;
119   case PRIM3D_RECTLIST:
120      return "RECTLIST";
121      break;
122   case PRIM3D_POINTLIST:
123      return "POINTLIST";
124      break;
125   case PRIM3D_DIB:
126      return "DIB";
127      break;
128   case PRIM3D_CLEAR_RECT:
129      return "CLEAR_RECT";
130      break;
131   case PRIM3D_ZONE_INIT:
132      return "ZONE_INIT";
133      break;
134   default:
135      return "????";
136      break;
137   }
138}
139
140static bool
141debug_prim(struct debug_stream *stream, const char *name, bool dump_floats,
142           unsigned len)
143{
144   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
145   const char *prim = get_prim_name(ptr[0]);
146   unsigned i;
147
148   mesa_logi("%s %s (%d dwords):", name, prim, len);
149   mesa_logi("\t0x%08x", ptr[0]);
150   for (i = 1; i < len; i++) {
151      if (dump_floats)
152         mesa_logi("\t0x%08x // %f", ptr[i], *(float *)&ptr[i]);
153      else
154         mesa_logi("\t0x%08x", ptr[i]);
155   }
156
157   mesa_logi("%s", "");
158
159   stream->offset += len * sizeof(unsigned);
160
161   return true;
162}
163
164static bool
165debug_program(struct debug_stream *stream, const char *name, unsigned len)
166{
167   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
168
169   if (len == 0) {
170      mesa_logi("Error - zero length packet (0x%08x)", stream->ptr[0]);
171      assert(0);
172      return false;
173   }
174
175   if (stream->print_addresses)
176      mesa_logi("%08x:  ", stream->offset);
177
178   mesa_logi("%s (%d dwords):", name, len);
179   i915_disassemble_program(ptr, len);
180
181   stream->offset += len * sizeof(unsigned);
182   return true;
183}
184
185static bool
186debug_chain(struct debug_stream *stream, const char *name, unsigned len)
187{
188   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
189   unsigned old_offset = stream->offset + len * sizeof(unsigned);
190   unsigned i;
191
192   mesa_logi("%s (%d dwords):", name, len);
193   for (i = 0; i < len; i++)
194      mesa_logi("\t0x%08x", ptr[i]);
195
196   stream->offset = ptr[1] & ~0x3;
197
198   if (stream->offset < old_offset)
199      mesa_logi("... skipping backwards from 0x%x --> 0x%x ...", old_offset,
200                stream->offset);
201   else
202      mesa_logi("... skipping from 0x%x --> 0x%x ...", old_offset,
203                stream->offset);
204
205   return true;
206}
207
208static bool
209debug_variable_length_prim(struct debug_stream *stream)
210{
211   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
212   const char *prim = get_prim_name(ptr[0]);
213   unsigned i, len;
214
215   ushort *idx = (ushort *)(ptr + 1);
216   for (i = 0; idx[i] != 0xffff; i++)
217      ;
218
219   len = 1 + (i + 2) / 2;
220
221   mesa_logi("3DPRIM, %s variable length %d indicies (%d dwords):", prim, i,
222             len);
223   for (i = 0; i < len; i++)
224      mesa_logi("\t0x%08x", ptr[i]);
225   mesa_logi("%s", "");
226
227   stream->offset += len * sizeof(unsigned);
228   return true;
229}
230
231static void
232BITS(struct debug_stream *stream, unsigned dw, unsigned hi, unsigned lo,
233     const char *fmt, ...)
234{
235   va_list args;
236   unsigned himask = 0xFFFFFFFFUL >> (31 - (hi));
237
238   va_start(args, fmt);
239   char *out = ralloc_vasprintf(NULL, fmt, args);
240   va_end(args);
241
242   mesa_logi("\t\t %s : 0x%x", out, ((dw)&himask) >> (lo));
243
244   ralloc_free(out);
245}
246
247#define MBZ(dw, hi, lo)                                                        \
248   do {                                                                        \
249      ASSERTED unsigned x = (dw) >> (lo);                                      \
250      ASSERTED unsigned lomask = (1 << (lo)) - 1;                              \
251      ASSERTED unsigned himask;                                                \
252      himask = (1UL << (hi)) - 1;                                              \
253      assert((x & himask & ~lomask) == 0);                                     \
254   } while (0)
255
256static void
257FLAG(struct debug_stream *stream, unsigned dw, unsigned bit, const char *fmt,
258     ...)
259{
260   if (((dw) >> (bit)) & 1) {
261      va_list args;
262      va_start(args, fmt);
263      char *out = ralloc_vasprintf(NULL, fmt, args);
264      va_end(args);
265
266      mesa_logi("\t\t %s", out);
267
268      ralloc_free(out);
269   }
270}
271
272static bool
273debug_load_immediate(struct debug_stream *stream, const char *name,
274                     unsigned len)
275{
276   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
277   unsigned bits = (ptr[0] >> 4) & 0xff;
278   unsigned j = 0;
279
280   mesa_logi("%s (%d dwords, flags: %x):", name, len, bits);
281   mesa_logi("\t0x%08x", ptr[j++]);
282
283   if (bits & (1 << 0)) {
284      mesa_logi("\t  LIS0: 0x%08x", ptr[j]);
285      mesa_logi("\t vb address: 0x%08x", (ptr[j] & ~0x3));
286      BITS(stream, ptr[j], 0, 0, "vb invalidate disable");
287      j++;
288   }
289   if (bits & (1 << 1)) {
290      mesa_logi("\t  LIS1: 0x%08x", ptr[j]);
291      BITS(stream, ptr[j], 29, 24, "vb dword width");
292      BITS(stream, ptr[j], 21, 16, "vb dword pitch");
293      BITS(stream, ptr[j], 15, 0, "vb max index");
294      j++;
295   }
296   if (bits & (1 << 2)) {
297      int i;
298      mesa_logi("\t  LIS2: 0x%08x", ptr[j]);
299      for (i = 0; i < 8; i++) {
300         unsigned tc = (ptr[j] >> (i * 4)) & 0xf;
301         if (tc != 0xf)
302            BITS(stream, tc, 3, 0, "tex coord %d", i);
303      }
304      j++;
305   }
306   if (bits & (1 << 3)) {
307      mesa_logi("\t  LIS3: 0x%08x", ptr[j]);
308      j++;
309   }
310   if (bits & (1 << 4)) {
311      mesa_logi("\t  LIS4: 0x%08x", ptr[j]);
312      BITS(stream, ptr[j], 31, 23, "point width");
313      BITS(stream, ptr[j], 22, 19, "line width");
314      FLAG(stream, ptr[j], 18, "alpha flatshade");
315      FLAG(stream, ptr[j], 17, "fog flatshade");
316      FLAG(stream, ptr[j], 16, "spec flatshade");
317      FLAG(stream, ptr[j], 15, "rgb flatshade");
318      BITS(stream, ptr[j], 14, 13, "cull mode");
319      FLAG(stream, ptr[j], 12, "vfmt: point width");
320      FLAG(stream, ptr[j], 11, "vfmt: specular/fog");
321      FLAG(stream, ptr[j], 10, "vfmt: rgba");
322      FLAG(stream, ptr[j], 9, "vfmt: depth offset");
323      BITS(stream, ptr[j], 8, 6, "vfmt: position (2==xyzw)");
324      FLAG(stream, ptr[j], 5, "force dflt diffuse");
325      FLAG(stream, ptr[j], 4, "force dflt specular");
326      FLAG(stream, ptr[j], 3, "local depth offset enable");
327      FLAG(stream, ptr[j], 2, "vfmt: fp32 fog coord");
328      FLAG(stream, ptr[j], 1, "sprite point");
329      FLAG(stream, ptr[j], 0, "antialiasing");
330      j++;
331   }
332   if (bits & (1 << 5)) {
333      mesa_logi("\t  LIS5: 0x%08x", ptr[j]);
334      BITS(stream, ptr[j], 31, 28, "rgba write disables");
335      FLAG(stream, ptr[j], 27, "force dflt point width");
336      FLAG(stream, ptr[j], 26, "last pixel enable");
337      FLAG(stream, ptr[j], 25, "global z offset enable");
338      FLAG(stream, ptr[j], 24, "fog enable");
339      BITS(stream, ptr[j], 23, 16, "stencil ref");
340      BITS(stream, ptr[j], 15, 13, "stencil test");
341      BITS(stream, ptr[j], 12, 10, "stencil fail op");
342      BITS(stream, ptr[j], 9, 7, "stencil pass z fail op");
343      BITS(stream, ptr[j], 6, 4, "stencil pass z pass op");
344      FLAG(stream, ptr[j], 3, "stencil write enable");
345      FLAG(stream, ptr[j], 2, "stencil test enable");
346      FLAG(stream, ptr[j], 1, "color dither enable");
347      FLAG(stream, ptr[j], 0, "logiop enable");
348      j++;
349   }
350   if (bits & (1 << 6)) {
351      mesa_logi("\t  LIS6: 0x%08x", ptr[j]);
352      FLAG(stream, ptr[j], 31, "alpha test enable");
353      BITS(stream, ptr[j], 30, 28, "alpha func");
354      BITS(stream, ptr[j], 27, 20, "alpha ref");
355      FLAG(stream, ptr[j], 19, "depth test enable");
356      BITS(stream, ptr[j], 18, 16, "depth func");
357      FLAG(stream, ptr[j], 15, "blend enable");
358      BITS(stream, ptr[j], 14, 12, "blend func");
359      BITS(stream, ptr[j], 11, 8, "blend src factor");
360      BITS(stream, ptr[j], 7, 4, "blend dst factor");
361      FLAG(stream, ptr[j], 3, "depth write enable");
362      FLAG(stream, ptr[j], 2, "color write enable");
363      BITS(stream, ptr[j], 1, 0, "provoking vertex");
364      j++;
365   }
366
367   mesa_logi("%s", "");
368
369   assert(j == len);
370
371   stream->offset += len * sizeof(unsigned);
372
373   return true;
374}
375
376static bool
377debug_load_indirect(struct debug_stream *stream, const char *name, unsigned len)
378{
379   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
380   unsigned bits = (ptr[0] >> 8) & 0x3f;
381   unsigned i, j = 0;
382
383   mesa_logi("%s (%d dwords):", name, len);
384   mesa_logi("\t0x%08x", ptr[j++]);
385
386   for (i = 0; i < 6; i++) {
387      if (bits & (1 << i)) {
388         switch (1 << (8 + i)) {
389         case LI0_STATE_STATIC_INDIRECT:
390            mesa_logi("        STATIC: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
391            j++;
392            mesa_logi("                0x%08x", ptr[j++]);
393            break;
394         case LI0_STATE_DYNAMIC_INDIRECT:
395            mesa_logi("       DYNAMIC: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
396            j++;
397            break;
398         case LI0_STATE_SAMPLER:
399            mesa_logi("       SAMPLER: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
400            j++;
401            mesa_logi("                0x%08x", ptr[j++]);
402            break;
403         case LI0_STATE_MAP:
404            mesa_logi("           MAP: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
405            j++;
406            mesa_logi("                0x%08x", ptr[j++]);
407            break;
408         case LI0_STATE_PROGRAM:
409            mesa_logi("       PROGRAM: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
410            j++;
411            mesa_logi("                0x%08x", ptr[j++]);
412            break;
413         case LI0_STATE_CONSTANTS:
414            mesa_logi("     CONSTANTS: 0x%08x | %x", ptr[j] & ~3, ptr[j] & 3);
415            j++;
416            mesa_logi("                0x%08x", ptr[j++]);
417            break;
418         default:
419            assert(0);
420            break;
421         }
422      }
423   }
424
425   if (bits == 0) {
426      mesa_logi("\t  DUMMY: 0x%08x", ptr[j++]);
427   }
428
429   mesa_logi("%s", "");
430
431   assert(j == len);
432
433   stream->offset += len * sizeof(unsigned);
434
435   return true;
436}
437
438static void
439BR13(struct debug_stream *stream, unsigned val)
440{
441   mesa_logi("\t0x%08x", val);
442   FLAG(stream, val, 30, "clipping enable");
443   BITS(stream, val, 25, 24, "color depth (3==32bpp)");
444   BITS(stream, val, 23, 16, "raster op");
445   BITS(stream, val, 15, 0, "dest pitch");
446}
447
448static void
449BR22(struct debug_stream *stream, unsigned val)
450{
451   mesa_logi("\t0x%08x", val);
452   BITS(stream, val, 31, 16, "dest y1");
453   BITS(stream, val, 15, 0, "dest x1");
454}
455
456static void
457BR23(struct debug_stream *stream, unsigned val)
458{
459   mesa_logi("\t0x%08x", val);
460   BITS(stream, val, 31, 16, "dest y2");
461   BITS(stream, val, 15, 0, "dest x2");
462}
463
464static void
465BR09(struct debug_stream *stream, unsigned val)
466{
467   mesa_logi("\t0x%08x -- dest address", val);
468}
469
470static void
471BR26(struct debug_stream *stream, unsigned val)
472{
473   mesa_logi("\t0x%08x", val);
474   BITS(stream, val, 31, 16, "src y1");
475   BITS(stream, val, 15, 0, "src x1");
476}
477
478static void
479BR11(struct debug_stream *stream, unsigned val)
480{
481   mesa_logi("\t0x%08x", val);
482   BITS(stream, val, 15, 0, "src pitch");
483}
484
485static void
486BR12(struct debug_stream *stream, unsigned val)
487{
488   mesa_logi("\t0x%08x -- src address", val);
489}
490
491static void
492BR16(struct debug_stream *stream, unsigned val)
493{
494   mesa_logi("\t0x%08x -- color", val);
495}
496
497static bool
498debug_copy_blit(struct debug_stream *stream, const char *name, unsigned len)
499{
500   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
501   int j = 0;
502
503   mesa_logi("%s (%d dwords):", name, len);
504   mesa_logi("\t0x%08x", ptr[j++]);
505
506   BR13(stream, ptr[j++]);
507   BR22(stream, ptr[j++]);
508   BR23(stream, ptr[j++]);
509   BR09(stream, ptr[j++]);
510   BR26(stream, ptr[j++]);
511   BR11(stream, ptr[j++]);
512   BR12(stream, ptr[j++]);
513
514   stream->offset += len * sizeof(unsigned);
515   assert(j == len);
516   return true;
517}
518
519static bool
520debug_color_blit(struct debug_stream *stream, const char *name, unsigned len)
521{
522   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
523   int j = 0;
524
525   mesa_logi("%s (%d dwords):", name, len);
526   mesa_logi("\t0x%08x", ptr[j++]);
527
528   BR13(stream, ptr[j++]);
529   BR22(stream, ptr[j++]);
530   BR23(stream, ptr[j++]);
531   BR09(stream, ptr[j++]);
532   BR16(stream, ptr[j++]);
533
534   stream->offset += len * sizeof(unsigned);
535   assert(j == len);
536   return true;
537}
538
539static bool
540debug_modes4(struct debug_stream *stream, const char *name, unsigned len)
541{
542   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
543   int j = 0;
544
545   mesa_logi("%s (%d dwords):", name, len);
546   mesa_logi("\t0x%08x", ptr[j]);
547   BITS(stream, ptr[j], 21, 18, "logicop func");
548   FLAG(stream, ptr[j], 17, "stencil test mask modify-enable");
549   FLAG(stream, ptr[j], 16, "stencil write mask modify-enable");
550   BITS(stream, ptr[j], 15, 8, "stencil test mask");
551   BITS(stream, ptr[j], 7, 0, "stencil write mask");
552   j++;
553
554   stream->offset += len * sizeof(unsigned);
555   assert(j == len);
556   return true;
557}
558
559static bool
560debug_map_state(struct debug_stream *stream, const char *name, unsigned len)
561{
562   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
563   unsigned j = 0;
564
565   mesa_logi("%s (%d dwords):", name, len);
566   mesa_logi("\t0x%08x", ptr[j++]);
567
568   {
569      mesa_logi("\t0x%08x", ptr[j]);
570      BITS(stream, ptr[j], 15, 0, "map mask");
571      j++;
572   }
573
574   while (j < len) {
575      {
576         mesa_logi("\t  TMn.0: 0x%08x", ptr[j]);
577         mesa_logi("\t map address: 0x%08x", (ptr[j] & ~0x3));
578         FLAG(stream, ptr[j], 1, "vertical line stride");
579         FLAG(stream, ptr[j], 0, "vertical line stride offset");
580         j++;
581      }
582
583      {
584         mesa_logi("\t  TMn.1: 0x%08x", ptr[j]);
585         BITS(stream, ptr[j], 31, 21, "height");
586         BITS(stream, ptr[j], 20, 10, "width");
587         BITS(stream, ptr[j], 9, 7, "surface format");
588         BITS(stream, ptr[j], 6, 3, "texel format");
589         FLAG(stream, ptr[j], 2, "use fence regs");
590         FLAG(stream, ptr[j], 1, "tiled surface");
591         FLAG(stream, ptr[j], 0, "tile walk ymajor");
592         j++;
593      }
594      {
595         mesa_logi("\t  TMn.2: 0x%08x", ptr[j]);
596         BITS(stream, ptr[j], 31, 21, "dword pitch");
597         BITS(stream, ptr[j], 20, 15, "cube face enables");
598         BITS(stream, ptr[j], 14, 9, "max lod");
599         FLAG(stream, ptr[j], 8, "mip layout right");
600         BITS(stream, ptr[j], 7, 0, "depth");
601         j++;
602      }
603   }
604
605   stream->offset += len * sizeof(unsigned);
606   assert(j == len);
607   return true;
608}
609
610static bool
611debug_sampler_state(struct debug_stream *stream, const char *name, unsigned len)
612{
613   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
614   unsigned j = 0;
615
616   mesa_logi("%s (%d dwords):", name, len);
617   mesa_logi("\t0x%08x", ptr[j++]);
618
619   {
620      mesa_logi("\t0x%08x", ptr[j]);
621      BITS(stream, ptr[j], 15, 0, "sampler mask");
622      j++;
623   }
624
625   while (j < len) {
626      {
627         mesa_logi("\t  TSn.0: 0x%08x", ptr[j]);
628         FLAG(stream, ptr[j], 31, "reverse gamma");
629         FLAG(stream, ptr[j], 30, "planar to packed");
630         FLAG(stream, ptr[j], 29, "yuv->rgb");
631         BITS(stream, ptr[j], 28, 27, "chromakey index");
632         BITS(stream, ptr[j], 26, 22, "base mip level");
633         BITS(stream, ptr[j], 21, 20, "mip mode filter");
634         BITS(stream, ptr[j], 19, 17, "mag mode filter");
635         BITS(stream, ptr[j], 16, 14, "min mode filter");
636         BITS(stream, ptr[j], 13, 5, "lod bias (s4.4)");
637         FLAG(stream, ptr[j], 4, "shadow enable");
638         FLAG(stream, ptr[j], 3, "max-aniso-4");
639         BITS(stream, ptr[j], 2, 0, "shadow func");
640         j++;
641      }
642
643      {
644         mesa_logi("\t  TSn.1: 0x%08x", ptr[j]);
645         BITS(stream, ptr[j], 31, 24, "min lod");
646         MBZ(ptr[j], 23, 18);
647         FLAG(stream, ptr[j], 17, "kill pixel enable");
648         FLAG(stream, ptr[j], 16, "keyed tex filter mode");
649         FLAG(stream, ptr[j], 15, "chromakey enable");
650         BITS(stream, ptr[j], 14, 12, "tcx wrap mode");
651         BITS(stream, ptr[j], 11, 9, "tcy wrap mode");
652         BITS(stream, ptr[j], 8, 6, "tcz wrap mode");
653         FLAG(stream, ptr[j], 5, "normalized coords");
654         BITS(stream, ptr[j], 4, 1, "map (surface) index");
655         FLAG(stream, ptr[j], 0, "EAST deinterlacer enable");
656         j++;
657      }
658      {
659         mesa_logi("\t  TSn.2: 0x%08x  (default color)", ptr[j]);
660         j++;
661      }
662   }
663
664   stream->offset += len * sizeof(unsigned);
665   assert(j == len);
666   return true;
667}
668
669static bool
670debug_dest_vars(struct debug_stream *stream, const char *name, unsigned len)
671{
672   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
673   int j = 0;
674
675   mesa_logi("%s (%d dwords):", name, len);
676   mesa_logi("\t0x%08x", ptr[j++]);
677
678   {
679      mesa_logi("\t0x%08x", ptr[j]);
680      FLAG(stream, ptr[j], 31, "early classic ztest");
681      FLAG(stream, ptr[j], 30, "opengl tex default color");
682      FLAG(stream, ptr[j], 29, "bypass iz");
683      FLAG(stream, ptr[j], 28, "lod preclamp");
684      BITS(stream, ptr[j], 27, 26, "dither pattern");
685      FLAG(stream, ptr[j], 25, "linear gamma blend");
686      FLAG(stream, ptr[j], 24, "debug dither");
687      BITS(stream, ptr[j], 23, 20, "dstorg x");
688      BITS(stream, ptr[j], 19, 16, "dstorg y");
689      MBZ(ptr[j], 15, 15);
690      BITS(stream, ptr[j], 14, 12, "422 write select");
691      BITS(stream, ptr[j], 11, 8, "cbuf format");
692      BITS(stream, ptr[j], 3, 2, "zbuf format");
693      FLAG(stream, ptr[j], 1, "vert line stride");
694      FLAG(stream, ptr[j], 1, "vert line stride offset");
695      j++;
696   }
697
698   stream->offset += len * sizeof(unsigned);
699   assert(j == len);
700   return true;
701}
702
703static bool
704debug_buf_info(struct debug_stream *stream, const char *name, unsigned len)
705{
706   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
707   int j = 0;
708
709   mesa_logi("%s (%d dwords):", name, len);
710   mesa_logi("\t0x%08x", ptr[j++]);
711
712   {
713      mesa_logi("\t0x%08x", ptr[j]);
714      BITS(stream, ptr[j], 28, 28, "aux buffer id");
715      BITS(stream, ptr[j], 27, 24, "buffer id (7=depth, 3=back)");
716      FLAG(stream, ptr[j], 23, "use fence regs");
717      FLAG(stream, ptr[j], 22, "tiled surface");
718      FLAG(stream, ptr[j], 21, "tile walk ymajor");
719      MBZ(ptr[j], 20, 14);
720      BITS(stream, ptr[j], 13, 2, "dword pitch");
721      MBZ(ptr[j], 2, 0);
722      j++;
723   }
724
725   mesa_logi("\t0x%08x -- buffer base address", ptr[j++]);
726
727   stream->offset += len * sizeof(unsigned);
728   assert(j == len);
729   return true;
730}
731
732static bool
733i915_debug_packet(struct debug_stream *stream)
734{
735   unsigned *ptr = (unsigned *)(stream->ptr + stream->offset);
736   unsigned cmd = *ptr;
737
738   switch (((cmd >> 29) & 0x7)) {
739   case 0x0:
740      switch ((cmd >> 23) & 0x3f) {
741      case 0x0:
742         return debug(stream, "MI_NOOP", 1);
743      case 0x3:
744         return debug(stream, "MI_WAIT_FOR_EVENT", 1);
745      case 0x4:
746         return debug(stream, "MI_FLUSH", 1);
747      case 0xA:
748         debug(stream, "MI_BATCH_BUFFER_END", 1);
749         return false;
750      case 0x22:
751         return debug(stream, "MI_LOAD_REGISTER_IMM", 3);
752      case 0x31:
753         return debug_chain(stream, "MI_BATCH_BUFFER_START", 2);
754      default:
755         (void)debug(stream, "UNKNOWN 0x0 case!", 1);
756         assert(0);
757         break;
758      }
759      break;
760   case 0x1:
761      (void)debug(stream, "UNKNOWN 0x1 case!", 1);
762      assert(0);
763      break;
764   case 0x2:
765      switch ((cmd >> 22) & 0xff) {
766      case 0x50:
767         return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2);
768      case 0x53:
769         return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2);
770      default:
771         return debug(stream, "blit command", (cmd & 0xff) + 2);
772      }
773      break;
774   case 0x3:
775      switch ((cmd >> 24) & 0x1f) {
776      case 0x6:
777         return debug(stream, "3DSTATE_ANTI_ALIASING", 1);
778      case 0x7:
779         return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1);
780      case 0x8:
781         return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 1);
782      case 0x9:
783         return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1);
784      case 0xb:
785         return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1);
786      case 0xc:
787         return debug(stream, "3DSTATE_MODES5", 1);
788      case 0xd:
789         return debug_modes4(stream, "3DSTATE_MODES4", 1);
790      case 0x15:
791         return debug(stream, "3DSTATE_FOG_COLOR", 1);
792      case 0x16:
793         return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1);
794      case 0x1c:
795         /* 3DState16NP */
796         switch ((cmd >> 19) & 0x1f) {
797         case 0x10:
798            return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1);
799         case 0x11:
800            return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1);
801         default:
802            (void)debug(stream, "UNKNOWN 0x1c case!", 1);
803            assert(0);
804            break;
805         }
806         break;
807      case 0x1d:
808         /* 3DStateMW */
809         switch ((cmd >> 16) & 0xff) {
810         case 0x0:
811            return debug_map_state(stream, "3DSTATE_MAP_STATE",
812                                   (cmd & 0x1f) + 2);
813         case 0x1:
814            return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE",
815                                       (cmd & 0x1f) + 2);
816         case 0x4:
817            return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE",
818                                        (cmd & 0xf) + 2);
819         case 0x5:
820            return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM",
821                                 (cmd & 0x1ff) + 2);
822         case 0x6:
823            return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS",
824                         (cmd & 0xff) + 2);
825         case 0x7:
826            return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT",
827                                       (cmd & 0xff) + 2);
828         case 0x80:
829            return debug(stream, "3DSTATE_DRAWING_RECTANGLE",
830                         (cmd & 0xffff) + 2);
831         case 0x81:
832            return debug(stream, "3DSTATE_SCISSOR_RECTANGLE",
833                         (cmd & 0xffff) + 2);
834         case 0x83:
835            return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2);
836         case 0x85:
837            return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS",
838                                   (cmd & 0xffff) + 2);
839         case 0x88:
840            return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR",
841                         (cmd & 0xffff) + 2);
842         case 0x89:
843            return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2);
844         case 0x8e:
845            return debug_buf_info(stream, "3DSTATE_BUFFER_INFO",
846                                  (cmd & 0xffff) + 2);
847         case 0x97:
848            return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE",
849                         (cmd & 0xffff) + 2);
850         case 0x98:
851            return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2);
852         case 0x99:
853            return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2);
854         case 0x9a:
855            return debug(stream, "3DSTATE_DEFAULT_SPECULAR",
856                         (cmd & 0xffff) + 2);
857         case 0x9c:
858            return debug(stream, "3DSTATE_CLEAR_PARAMETERS",
859                         (cmd & 0xffff) + 2);
860         default:
861            assert(0);
862            return 0;
863         }
864         break;
865      case 0x1e:
866         if (cmd & (1 << 23))
867            return debug(stream, "???", (cmd & 0xffff) + 1);
868         else
869            return debug(stream, "", 1);
870         break;
871      case 0x1f:
872         if ((cmd & (1 << 23)) == 0)
873            return debug_prim(stream, "3DPRIM (inline)", 1,
874                              (cmd & 0x1ffff) + 2);
875         else if (cmd & (1 << 17)) {
876            if ((cmd & 0xffff) == 0)
877               return debug_variable_length_prim(stream);
878            else
879               return debug_prim(stream, "3DPRIM (indexed)", 0,
880                                 (((cmd & 0xffff) + 1) / 2) + 1);
881         } else
882            return debug_prim(stream, "3DPRIM  (indirect sequential)", 0, 2);
883         break;
884      default:
885         return debug(stream, "", 0);
886      }
887      break;
888   default:
889      assert(0);
890      return 0;
891   }
892
893   assert(0);
894   return 0;
895}
896
897void
898i915_dump_batchbuffer(struct i915_winsys_batchbuffer *batch)
899{
900   struct debug_stream stream;
901   unsigned *start = (unsigned *)batch->map;
902   unsigned *end = (unsigned *)batch->ptr;
903   unsigned long bytes = (unsigned long)(end - start) * 4;
904   bool done = false;
905
906   stream.offset = 0;
907   stream.ptr = (char *)start;
908   stream.print_addresses = 0;
909
910   if (!start || !end) {
911      mesa_logi("BATCH: ???");
912      return;
913   }
914
915   mesa_logi("BATCH: (%d)", (int)bytes / 4);
916
917   while (!done && stream.offset < bytes) {
918      if (!i915_debug_packet(&stream))
919         break;
920
921      assert(stream.offset <= bytes);
922   }
923
924   mesa_logi("END-BATCH");
925}
926
927/***********************************************************************
928 * Dirty state atom dumping
929 */
930
931void
932i915_dump_dirty(struct i915_context *i915, const char *func)
933{
934   struct {
935      unsigned dirty;
936      const char *name;
937   } l[] = {
938      {I915_NEW_VIEWPORT, "viewport"},
939      {I915_NEW_RASTERIZER, "rasterizer"},
940      {I915_NEW_FS, "fs"},
941      {I915_NEW_BLEND, "blend"},
942      {I915_NEW_CLIP, "clip"},
943      {I915_NEW_SCISSOR, "scissor"},
944      {I915_NEW_STIPPLE, "stipple"},
945      {I915_NEW_FRAMEBUFFER, "framebuffer"},
946      {I915_NEW_ALPHA_TEST, "alpha_test"},
947      {I915_NEW_DEPTH_STENCIL, "depth_stencil"},
948      {I915_NEW_SAMPLER, "sampler"},
949      {I915_NEW_SAMPLER_VIEW, "sampler_view"},
950      {I915_NEW_VS_CONSTANTS, "vs_const"},
951      {I915_NEW_FS_CONSTANTS, "fs_const"},
952      {I915_NEW_VBO, "vbo"},
953      {I915_NEW_VS, "vs"},
954      {0, NULL},
955   };
956   int i;
957
958   mesa_logi("%s: ", func);
959   for (i = 0; l[i].name; i++)
960      if (i915->dirty & l[i].dirty)
961         mesa_logi("%s ", l[i].name);
962   mesa_logi("%s", "");
963}
964
965void
966i915_dump_hardware_dirty(struct i915_context *i915, const char *func)
967{
968   struct {
969      unsigned dirty;
970      const char *name;
971   } l[] = {
972      {I915_HW_STATIC, "static"},
973      {I915_HW_DYNAMIC, "dynamic"},
974      {I915_HW_SAMPLER, "sampler"},
975      {I915_HW_MAP, "map"},
976      {I915_HW_PROGRAM, "program"},
977      {I915_HW_CONSTANTS, "constants"},
978      {I915_HW_IMMEDIATE, "immediate"},
979      {I915_HW_INVARIANT, "invariant"},
980      {0, NULL},
981   };
982   int i;
983
984   mesa_logi("%s: ", func);
985   for (i = 0; l[i].name; i++)
986      if (i915->hardware_dirty & l[i].dirty)
987         mesa_logi("%s ", l[i].name);
988   mesa_logi("%s", "");
989}
990