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