i965: Dump the binding table using state_batch_list[].
[mesa.git] / src / mesa / drivers / dri / i965 / brw_state_dump.c
1 /*
2 * Copyright © 2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28 #include "main/mtypes.h"
29 #include "intel_batchbuffer.h"
30
31 #include "brw_context.h"
32 #include "brw_defines.h"
33
34 static void
35 batch_out(struct brw_context *brw, const char *name, uint32_t offset,
36 int index, char *fmt, ...) PRINTFLIKE(5, 6);
37
38 /**
39 * Prints out a header, the contents, and the message associated with
40 * the hardware state data given.
41 *
42 * \param name Name of the state object
43 * \param data Pointer to the base of the state object
44 * \param hw_offset Hardware offset of the base of the state data.
45 * \param index Index of the DWORD being output.
46 */
47 static void
48 state_out(const char *name, void *data, uint32_t hw_offset, int index,
49 char *fmt, ...)
50 {
51 va_list va;
52
53 fprintf(stderr, "%8s: 0x%08x: 0x%08x: ",
54 name, hw_offset + index * 4, ((uint32_t *)data)[index]);
55 va_start(va, fmt);
56 vfprintf(stderr, fmt, va);
57 va_end(va);
58 }
59
60 static void
61 batch_out(struct brw_context *brw, const char *name, uint32_t offset,
62 int index, char *fmt, ...)
63 {
64 struct intel_context *intel = &brw->intel;
65 uint32_t *data = intel->batch.bo->virtual + offset;
66 va_list va;
67
68 fprintf(stderr, "0x%08x: 0x%08x: %8s: ",
69 offset + index * 4, data[index], name);
70 va_start(va, fmt);
71 vfprintf(stderr, fmt, va);
72 va_end(va);
73 }
74
75 /** Generic, undecoded state buffer debug printout */
76 static void
77 state_struct_out(const char *name, drm_intel_bo *buffer,
78 unsigned int offset, unsigned int size)
79 {
80 int i;
81
82 if (buffer == NULL)
83 return;
84
85 drm_intel_bo_map(buffer, GL_FALSE);
86 for (i = 0; i < size / 4; i++) {
87 state_out(name, buffer->virtual + offset, buffer->offset + offset, i,
88 "dword %d\n", i);
89 }
90 drm_intel_bo_unmap(buffer);
91 }
92
93 static const char *
94 get_965_surfacetype(unsigned int surfacetype)
95 {
96 switch (surfacetype) {
97 case 0: return "1D";
98 case 1: return "2D";
99 case 2: return "3D";
100 case 3: return "CUBE";
101 case 4: return "BUFFER";
102 case 7: return "NULL";
103 default: return "unknown";
104 }
105 }
106
107 static const char *
108 get_965_surface_format(unsigned int surface_format)
109 {
110 switch (surface_format) {
111 case 0x000: return "r32g32b32a32_float";
112 case 0x0c1: return "b8g8r8a8_unorm";
113 case 0x100: return "b5g6r5_unorm";
114 case 0x102: return "b5g5r5a1_unorm";
115 case 0x104: return "b4g4r4a4_unorm";
116 default: return "unknown";
117 }
118 }
119
120 static void dump_surface_state(struct brw_context *brw, uint32_t offset)
121 {
122 const char *name = "SURF";
123 uint32_t *surf = brw->intel.batch.bo->virtual + offset;
124
125 batch_out(brw, name, offset, 0, "%s %s\n",
126 get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
127 get_965_surface_format(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)));
128 batch_out(brw, name, offset, 1, "offset\n");
129 batch_out(brw, name, offset, 2, "%dx%d size, %d mips\n",
130 GET_FIELD(surf[2], BRW_SURFACE_WIDTH) + 1,
131 GET_FIELD(surf[2], BRW_SURFACE_HEIGHT) + 1,
132 GET_FIELD(surf[2], BRW_SURFACE_LOD));
133 batch_out(brw, name, offset, 3, "pitch %d, %s tiled\n",
134 GET_FIELD(surf[3], BRW_SURFACE_PITCH) + 1,
135 (surf[3] & BRW_SURFACE_TILED) ?
136 ((surf[3] & BRW_SURFACE_TILED_Y) ? "Y" : "X") : "not");
137 batch_out(brw, name, offset, 4, "mip base %d\n",
138 GET_FIELD(surf[4], BRW_SURFACE_MIN_LOD));
139 batch_out(brw, name, offset, 5, "x,y offset: %d,%d\n",
140 GET_FIELD(surf[5], BRW_SURFACE_X_OFFSET),
141 GET_FIELD(surf[5], BRW_SURFACE_Y_OFFSET));
142 }
143
144 static void dump_gen7_surface_state(struct brw_context *brw, uint32_t offset)
145 {
146 const char *name = "SURF";
147 struct gen7_surface_state *surf = brw->intel.batch.bo->virtual + offset;
148
149 batch_out(brw, name, offset, 0, "%s %s\n",
150 get_965_surfacetype(surf->ss0.surface_type),
151 get_965_surface_format(surf->ss0.surface_format));
152 batch_out(brw, name, offset, 1, "offset\n");
153 batch_out(brw, name, offset, 2, "%dx%d size, %d mips\n",
154 surf->ss2.width + 1, surf->ss2.height + 1, surf->ss5.mip_count);
155 batch_out(brw, name, offset, 3, "pitch %d, %stiled\n",
156 surf->ss3.pitch + 1, surf->ss0.tiled_surface ? "" : "not ");
157 batch_out(brw, name, offset, 4, "mip base %d\n",
158 surf->ss5.min_lod);
159 batch_out(brw, name, offset, 5, "x,y offset: %d,%d\n",
160 surf->ss5.x_offset, surf->ss5.y_offset);
161 }
162
163 static void
164 dump_sdc(struct brw_context *brw, uint32_t offset)
165 {
166 const char *name = "SDC";
167 struct intel_context *intel = &brw->intel;
168
169 if (intel->gen >= 5 && intel->gen <= 6) {
170 struct gen5_sampler_default_color *sdc = (intel->batch.bo->virtual +
171 offset);
172 batch_out(brw, name, offset, 0, "unorm rgba\n");
173 batch_out(brw, name, offset, 1, "r %f\n", sdc->f[0]);
174 batch_out(brw, name, offset, 2, "b %f\n", sdc->f[1]);
175 batch_out(brw, name, offset, 3, "g %f\n", sdc->f[2]);
176 batch_out(brw, name, offset, 4, "a %f\n", sdc->f[3]);
177 batch_out(brw, name, offset, 5, "half float rg\n");
178 batch_out(brw, name, offset, 6, "half float ba\n");
179 batch_out(brw, name, offset, 7, "u16 rg\n");
180 batch_out(brw, name, offset, 8, "u16 ba\n");
181 batch_out(brw, name, offset, 9, "s16 rg\n");
182 batch_out(brw, name, offset, 10, "s16 ba\n");
183 batch_out(brw, name, offset, 11, "s8 rgba\n");
184 } else {
185 struct brw_sampler_default_color *sdc = (intel->batch.bo->virtual +
186 offset);
187 batch_out(brw, name, offset, 0, "r %f\n", sdc->color[0]);
188 batch_out(brw, name, offset, 1, "g %f\n", sdc->color[1]);
189 batch_out(brw, name, offset, 2, "b %f\n", sdc->color[2]);
190 batch_out(brw, name, offset, 3, "a %f\n", sdc->color[3]);
191 }
192 }
193
194 static void dump_sampler_state(struct brw_context *brw,
195 uint32_t offset, uint32_t size)
196 {
197 struct intel_context *intel = &brw->intel;
198 int i;
199 struct brw_sampler_state *samp = intel->batch.bo->virtual + offset;
200
201 assert(intel->gen < 7);
202
203 for (i = 0; i < size / sizeof(*samp); i++) {
204 char name[20];
205
206 sprintf(name, "WM SAMP%d", i);
207 batch_out(brw, name, offset, 0, "filtering\n");
208 batch_out(brw, name, offset, 1, "wrapping, lod\n");
209 batch_out(brw, name, offset, 2, "default color pointer\n");
210 batch_out(brw, name, offset, 3, "chroma key, aniso\n");
211
212 samp++;
213 offset += sizeof(*samp);
214 }
215 }
216
217 static void dump_gen7_sampler_state(struct brw_context *brw,
218 uint32_t offset, uint32_t size)
219 {
220 struct intel_context *intel = &brw->intel;
221 struct gen7_sampler_state *samp = intel->batch.bo->virtual + offset;
222 int i;
223
224 assert(intel->gen >= 7);
225
226 for (i = 0; i < size / sizeof(*samp); i++) {
227 char name[20];
228
229 sprintf(name, "WM SAMP%d", i);
230 batch_out(brw, name, offset, 0, "filtering\n");
231 batch_out(brw, name, offset, 1, "wrapping, lod\n");
232 batch_out(brw, name, offset, 2, "default color pointer\n");
233 batch_out(brw, name, offset, 3, "chroma key, aniso\n");
234
235 samp++;
236 offset += sizeof(*samp);
237 }
238 drm_intel_bo_unmap(intel->batch.bo);
239 }
240
241
242 static void dump_sf_viewport_state(struct brw_context *brw,
243 uint32_t offset)
244 {
245 struct intel_context *intel = &brw->intel;
246 const char *name = "SF VP";
247 struct brw_sf_viewport *vp = intel->batch.bo->virtual + offset;
248
249 assert(intel->gen < 7);
250
251 batch_out(brw, name, offset, 0, "m00 = %f\n", vp->viewport.m00);
252 batch_out(brw, name, offset, 1, "m11 = %f\n", vp->viewport.m11);
253 batch_out(brw, name, offset, 2, "m22 = %f\n", vp->viewport.m22);
254 batch_out(brw, name, offset, 3, "m30 = %f\n", vp->viewport.m30);
255 batch_out(brw, name, offset, 4, "m31 = %f\n", vp->viewport.m31);
256 batch_out(brw, name, offset, 5, "m32 = %f\n", vp->viewport.m32);
257
258 batch_out(brw, name, offset, 6, "top left = %d,%d\n",
259 vp->scissor.xmin, vp->scissor.ymin);
260 batch_out(brw, name, offset, 7, "bottom right = %d,%d\n",
261 vp->scissor.xmax, vp->scissor.ymax);
262 }
263
264 static void dump_clip_viewport_state(struct brw_context *brw,
265 uint32_t offset)
266 {
267 struct intel_context *intel = &brw->intel;
268 const char *name = "CLIP VP";
269 struct brw_clipper_viewport *vp = intel->batch.bo->virtual + offset;
270
271 assert(intel->gen < 7);
272
273 batch_out(brw, name, offset, 0, "xmin = %f\n", vp->xmin);
274 batch_out(brw, name, offset, 1, "xmax = %f\n", vp->xmax);
275 batch_out(brw, name, offset, 2, "ymin = %f\n", vp->ymin);
276 batch_out(brw, name, offset, 3, "ymax = %f\n", vp->ymax);
277 }
278
279 static void dump_sf_clip_viewport_state(struct brw_context *brw,
280 uint32_t offset)
281 {
282 struct intel_context *intel = &brw->intel;
283 const char *name = "SF_CLIP VP";
284 struct gen7_sf_clip_viewport *vp = intel->batch.bo->virtual + offset;
285
286 assert(intel->gen >= 7);
287
288 batch_out(brw, name, offset, 0, "m00 = %f\n", vp->viewport.m00);
289 batch_out(brw, name, offset, 1, "m11 = %f\n", vp->viewport.m11);
290 batch_out(brw, name, offset, 2, "m22 = %f\n", vp->viewport.m22);
291 batch_out(brw, name, offset, 3, "m30 = %f\n", vp->viewport.m30);
292 batch_out(brw, name, offset, 4, "m31 = %f\n", vp->viewport.m31);
293 batch_out(brw, name, offset, 5, "m32 = %f\n", vp->viewport.m32);
294 batch_out(brw, name, offset, 6, "guardband xmin = %f\n", vp->guardband.xmin);
295 batch_out(brw, name, offset, 7, "guardband xmax = %f\n", vp->guardband.xmax);
296 batch_out(brw, name, offset, 8, "guardband ymin = %f\n", vp->guardband.ymin);
297 batch_out(brw, name, offset, 9, "guardband ymax = %f\n", vp->guardband.ymax);
298 }
299
300
301 static void dump_cc_viewport_state(struct brw_context *brw, uint32_t offset)
302 {
303 const char *name = "CC VP";
304 struct brw_cc_viewport *vp = brw->intel.batch.bo->virtual + offset;
305
306 batch_out(brw, name, offset, 0, "min_depth = %f\n", vp->min_depth);
307 batch_out(brw, name, offset, 1, "max_depth = %f\n", vp->max_depth);
308 }
309
310 static void dump_depth_stencil_state(struct brw_context *brw, uint32_t offset)
311 {
312 const char *name = "D_S";
313 struct gen6_depth_stencil_state *ds = brw->intel.batch.bo->virtual + offset;
314
315 batch_out(brw, name, offset, 0,
316 "stencil %sable, func %d, write %sable\n",
317 ds->ds0.stencil_enable ? "en" : "dis",
318 ds->ds0.stencil_func,
319 ds->ds0.stencil_write_enable ? "en" : "dis");
320 batch_out(brw, name, offset, 1,
321 "stencil test mask 0x%x, write mask 0x%x\n",
322 ds->ds1.stencil_test_mask, ds->ds1.stencil_write_mask);
323 batch_out(brw, name, offset, 2,
324 "depth test %sable, func %d, write %sable\n",
325 ds->ds2.depth_test_enable ? "en" : "dis",
326 ds->ds2.depth_test_func,
327 ds->ds2.depth_write_enable ? "en" : "dis");
328 }
329
330 static void dump_cc_state(struct brw_context *brw, uint32_t offset)
331 {
332 const char *name = "CC";
333 struct gen6_color_calc_state *cc = brw->intel.batch.bo->virtual + offset;
334
335 batch_out(brw, name, offset, 0,
336 "alpha test format %s, round disable %d, stencil ref %d, "
337 "bf stencil ref %d\n",
338 cc->cc0.alpha_test_format ? "FLOAT32" : "UNORM8",
339 cc->cc0.round_disable,
340 cc->cc0.stencil_ref,
341 cc->cc0.bf_stencil_ref);
342 batch_out(brw, name, offset, 1, "\n");
343 batch_out(brw, name, offset, 2, "constant red %f\n", cc->constant_r);
344 batch_out(brw, name, offset, 3, "constant green %f\n", cc->constant_g);
345 batch_out(brw, name, offset, 4, "constant blue %f\n", cc->constant_b);
346 batch_out(brw, name, offset, 5, "constant alpha %f\n", cc->constant_a);
347 }
348
349 static void dump_blend_state(struct brw_context *brw, uint32_t offset)
350 {
351 const char *name = "BLEND";
352
353 batch_out(brw, name, offset, 0, "\n");
354 batch_out(brw, name, offset, 1, "\n");
355 }
356
357 static void dump_binding_table(struct brw_context *brw, uint32_t offset,
358 uint32_t size)
359 {
360 char name[20];
361 int i;
362 uint32_t *data = brw->intel.batch.bo->virtual + offset;
363
364 for (i = 0; i < size / 4; i++) {
365 if (data[i] == 0)
366 continue;
367
368 sprintf(name, "BIND%d", i);
369 batch_out(brw, name, offset, i, "surface state address\n");
370 }
371 }
372
373 static void brw_debug_prog(struct brw_context *brw,
374 const char *name, uint32_t prog_offset)
375 {
376 unsigned int i;
377 uint32_t *data;
378
379 drm_intel_bo_map(brw->cache.bo, false);
380
381 data = brw->cache.bo->virtual + prog_offset;
382
383 for (i = 0; i < brw->cache.bo->size / 4 / 4; i++) {
384 fprintf(stderr, "%8s: 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
385 name, (unsigned int)brw->cache.bo->offset + i * 4 * 4,
386 data[i * 4], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]);
387 /* Stop at the end of the program. It'd be nice to keep track of the actual
388 * intended program size instead of guessing like this.
389 */
390 if (data[i * 4 + 0] == 0 &&
391 data[i * 4 + 1] == 0 &&
392 data[i * 4 + 2] == 0 &&
393 data[i * 4 + 3] == 0)
394 break;
395 }
396
397 drm_intel_bo_unmap(brw->cache.bo);
398 }
399
400 static void
401 dump_state_batch(struct brw_context *brw)
402 {
403 struct intel_context *intel = &brw->intel;
404 int i;
405
406 for (i = 0; i < brw->state_batch_count; i++) {
407 uint32_t offset = brw->state_batch_list[i].offset;
408 uint32_t size = brw->state_batch_list[i].size;
409
410 switch (brw->state_batch_list[i].type) {
411 case AUB_TRACE_CLIP_VP_STATE:
412 dump_clip_viewport_state(brw, offset);
413 break;
414 case AUB_TRACE_SF_VP_STATE:
415 if (intel->gen >= 7) {
416 dump_sf_clip_viewport_state(brw, offset);
417 } else {
418 dump_sf_viewport_state(brw, offset);
419 }
420 break;
421 case AUB_TRACE_CC_VP_STATE:
422 dump_cc_viewport_state(brw, offset);
423 break;
424 case AUB_TRACE_DEPTH_STENCIL_STATE:
425 dump_depth_stencil_state(brw, offset);
426 break;
427 case AUB_TRACE_CC_STATE:
428 dump_cc_state(brw, offset);
429 break;
430 case AUB_TRACE_BLEND_STATE:
431 dump_blend_state(brw, offset);
432 break;
433 case AUB_TRACE_BINDING_TABLE:
434 dump_binding_table(brw, offset, size);
435 break;
436 case AUB_TRACE_SURFACE_STATE:
437 if (intel->gen < 7) {
438 dump_surface_state(brw, offset);
439 } else {
440 dump_gen7_surface_state(brw, offset);
441 }
442 break;
443 case AUB_TRACE_SAMPLER_STATE:
444 if (intel->gen < 7) {
445 dump_sampler_state(brw, offset, size);
446 } else {
447 dump_gen7_sampler_state(brw, offset, size);
448 }
449 break;
450 case AUB_TRACE_SAMPLER_DEFAULT_COLOR:
451 dump_sdc(brw, offset);
452 break;
453 default:
454 break;
455 }
456 }
457 }
458
459 /**
460 * Print additional debug information associated with the batchbuffer
461 * when DEBUG_BATCH is set.
462 *
463 * For 965, this means mapping the state buffers that would have been referenced
464 * by the batchbuffer and dumping them.
465 *
466 * The buffer offsets printed rely on the buffer containing the last offset
467 * it was validated at.
468 */
469 void brw_debug_batch(struct intel_context *intel)
470 {
471 struct brw_context *brw = brw_context(&intel->ctx);
472
473 if (intel->gen < 6)
474 state_struct_out("VS", intel->batch.bo, brw->vs.state_offset,
475 sizeof(struct brw_vs_unit_state));
476 brw_debug_prog(brw, "VS prog", brw->vs.prog_offset);
477
478 if (intel->gen < 6)
479 state_struct_out("GS", intel->batch.bo, brw->gs.state_offset,
480 sizeof(struct brw_gs_unit_state));
481 if (brw->gs.prog_active) {
482 brw_debug_prog(brw, "GS prog", brw->gs.prog_offset);
483 }
484
485 if (intel->gen < 6) {
486 state_struct_out("SF", intel->batch.bo, brw->sf.state_offset,
487 sizeof(struct brw_sf_unit_state));
488 brw_debug_prog(brw, "SF prog", brw->sf.prog_offset);
489 }
490
491 if (intel->gen < 6)
492 state_struct_out("WM", intel->batch.bo, brw->wm.state_offset,
493 sizeof(struct brw_wm_unit_state));
494 brw_debug_prog(brw, "WM prog", brw->wm.prog_offset);
495
496 drm_intel_bo_map(intel->batch.bo, false);
497 dump_state_batch(brw);
498 drm_intel_bo_unmap(intel->batch.bo);
499 }