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