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_lie, "I915_LIE", true)
54 DEBUG_GET_ONCE_BOOL_OPTION(i915_use_blitter, "I915_USE_BLITTER", true)
55 
56 void
i915_debug_init(struct i915_screen * is)57 i915_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 
69 static bool
debug(struct debug_stream * stream,const char * name,unsigned len)70 debug(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 
94 static const char *
get_prim_name(unsigned val)95 get_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 
140 static bool
debug_prim(struct debug_stream * stream,const char * name,bool dump_floats,unsigned len)141 debug_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 
164 static bool
debug_program(struct debug_stream * stream,const char * name,unsigned len)165 debug_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 
185 static bool
debug_chain(struct debug_stream * stream,const char * name,unsigned len)186 debug_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 
208 static bool
debug_variable_length_prim(struct debug_stream * stream)209 debug_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 
231 static void
BITS(struct debug_stream * stream,unsigned dw,unsigned hi,unsigned lo,const char * fmt,...)232 BITS(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 
256 static void
FLAG(struct debug_stream * stream,unsigned dw,unsigned bit,const char * fmt,...)257 FLAG(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 
272 static bool
debug_load_immediate(struct debug_stream * stream,const char * name,unsigned len)273 debug_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 
376 static bool
debug_load_indirect(struct debug_stream * stream,const char * name,unsigned len)377 debug_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 
438 static void
BR13(struct debug_stream * stream,unsigned val)439 BR13(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 
448 static void
BR22(struct debug_stream * stream,unsigned val)449 BR22(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 
456 static void
BR23(struct debug_stream * stream,unsigned val)457 BR23(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 
464 static void
BR09(struct debug_stream * stream,unsigned val)465 BR09(struct debug_stream *stream, unsigned val)
466 {
467    mesa_logi("\t0x%08x -- dest address", val);
468 }
469 
470 static void
BR26(struct debug_stream * stream,unsigned val)471 BR26(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 
478 static void
BR11(struct debug_stream * stream,unsigned val)479 BR11(struct debug_stream *stream, unsigned val)
480 {
481    mesa_logi("\t0x%08x", val);
482    BITS(stream, val, 15, 0, "src pitch");
483 }
484 
485 static void
BR12(struct debug_stream * stream,unsigned val)486 BR12(struct debug_stream *stream, unsigned val)
487 {
488    mesa_logi("\t0x%08x -- src address", val);
489 }
490 
491 static void
BR16(struct debug_stream * stream,unsigned val)492 BR16(struct debug_stream *stream, unsigned val)
493 {
494    mesa_logi("\t0x%08x -- color", val);
495 }
496 
497 static bool
debug_copy_blit(struct debug_stream * stream,const char * name,unsigned len)498 debug_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 
519 static bool
debug_color_blit(struct debug_stream * stream,const char * name,unsigned len)520 debug_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 
539 static bool
debug_modes4(struct debug_stream * stream,const char * name,unsigned len)540 debug_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 
559 static bool
debug_map_state(struct debug_stream * stream,const char * name,unsigned len)560 debug_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 
610 static bool
debug_sampler_state(struct debug_stream * stream,const char * name,unsigned len)611 debug_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 
669 static bool
debug_dest_vars(struct debug_stream * stream,const char * name,unsigned len)670 debug_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 
703 static bool
debug_buf_info(struct debug_stream * stream,const char * name,unsigned len)704 debug_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 
732 static bool
i915_debug_packet(struct debug_stream * stream)733 i915_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 
897 void
i915_dump_batchbuffer(struct i915_winsys_batchbuffer * batch)898 i915_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 
931 void
i915_dump_dirty(struct i915_context * i915,const char * func)932 i915_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 
965 void
i915_dump_hardware_dirty(struct i915_context * i915,const char * func)966 i915_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