1/*
2 * Copyright © 2007-2015 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 "isl/isl.h"
32
33#include "brw_context.h"
34#include "brw_defines.h"
35#include "brw_eu.h"
36#include "brw_state.h"
37
38static const char *sampler_mip_filter[] = {
39   "NONE",
40   "NEAREST",
41   "RSVD",
42   "LINEAR"
43};
44
45static const char *sampler_mag_filter[] = {
46   "NEAREST",
47   "LINEAR",
48   "ANISOTROPIC",
49   "FLEXIBLE (GEN8+)",
50   "RSVD", "RSVD",
51   "MONO",
52   "RSVD"
53};
54
55static const char *sampler_addr_mode[] = {
56   "WRAP",
57   "MIRROR",
58   "CLAMP",
59   "CUBE",
60   "CLAMP_BORDER",
61   "MIRROR_ONCE",
62   "HALF_BORDER"
63};
64
65static const char *surface_tiling[] = {
66   "LINEAR",
67   "W-tiled",
68   "X-tiled",
69   "Y-tiled"
70};
71
72static void
73batch_out(struct brw_context *brw, const char *name, uint32_t offset,
74	  int index, char *fmt, ...) PRINTFLIKE(5, 6);
75
76static void
77batch_out(struct brw_context *brw, const char *name, uint32_t offset,
78	  int index, char *fmt, ...)
79{
80   uint32_t *data = brw->batch.bo->virtual + offset;
81   va_list va;
82
83   fprintf(stderr, "0x%08x:      0x%08x: %8s: ",
84	   offset + index * 4, data[index], name);
85   va_start(va, fmt);
86   vfprintf(stderr, fmt, va);
87   va_end(va);
88}
89
90static void
91batch_out64(struct brw_context *brw, const char *name, uint32_t offset,
92            int index, char *fmt, ...)
93{
94   uint32_t *tmp = brw->batch.bo->virtual + offset;
95
96   /* Swap the dwords since we want to handle this as a 64b value, but the data
97    * is typically emitted as dwords.
98    */
99   uint64_t data = ((uint64_t)tmp[index + 1]) << 32 | tmp[index];
100   va_list va;
101
102   fprintf(stderr, "0x%08x:      0x%016" PRIx64 ": %8s: ",
103          offset + index * 4, data, name);
104   va_start(va, fmt);
105   vfprintf(stderr, fmt, va);
106   va_end(va);
107}
108
109static const char *
110get_965_surfacetype(unsigned int surfacetype)
111{
112    switch (surfacetype) {
113    case 0: return "1D";
114    case 1: return "2D";
115    case 2: return "3D";
116    case 3: return "CUBE";
117    case 4: return "BUFFER";
118    case 7: return "NULL";
119    default: return "unknown";
120    }
121}
122
123static void dump_vs_state(struct brw_context *brw, uint32_t offset)
124{
125   const char *name = "VS_STATE";
126   struct brw_vs_unit_state *vs = brw->batch.bo->virtual + offset;
127
128   batch_out(brw, name, offset, 0, "thread0\n");
129   batch_out(brw, name, offset, 1, "thread1\n");
130   batch_out(brw, name, offset, 2, "thread2\n");
131   batch_out(brw, name, offset, 3, "thread3\n");
132   batch_out(brw, name, offset, 4, "thread4: %d threads\n",
133	     vs->thread4.max_threads + 1);
134   batch_out(brw, name, offset, 5, "vs5\n");
135   batch_out(brw, name, offset, 6, "vs6\n");
136}
137
138static void dump_gs_state(struct brw_context *brw, uint32_t offset)
139{
140   const char *name = "GS_STATE";
141   struct brw_gs_unit_state *gs = brw->batch.bo->virtual + offset;
142
143   batch_out(brw, name, offset, 0, "thread0\n");
144   batch_out(brw, name, offset, 1, "thread1\n");
145   batch_out(brw, name, offset, 2, "thread2\n");
146   batch_out(brw, name, offset, 3, "thread3\n");
147   batch_out(brw, name, offset, 4, "thread4: %d threads\n",
148	     gs->thread4.max_threads + 1);
149   batch_out(brw, name, offset, 5, "vs5\n");
150   batch_out(brw, name, offset, 6, "vs6\n");
151}
152
153static void dump_clip_state(struct brw_context *brw, uint32_t offset)
154{
155   const char *name = "CLIP_STATE";
156   struct brw_clip_unit_state *clip = brw->batch.bo->virtual + offset;
157
158   batch_out(brw, name, offset, 0, "thread0\n");
159   batch_out(brw, name, offset, 1, "thread1\n");
160   batch_out(brw, name, offset, 2, "thread2\n");
161   batch_out(brw, name, offset, 3, "thread3\n");
162   batch_out(brw, name, offset, 4, "thread4: %d threads\n",
163	     clip->thread4.max_threads + 1);
164   batch_out(brw, name, offset, 5, "clip5\n");
165   batch_out(brw, name, offset, 6, "clip6\n");
166   batch_out(brw, name, offset, 7, "vp xmin %f\n", clip->viewport_xmin);
167   batch_out(brw, name, offset, 8, "vp xmax %f\n", clip->viewport_xmax);
168   batch_out(brw, name, offset, 9, "vp ymin %f\n", clip->viewport_ymin);
169   batch_out(brw, name, offset, 10, "vp ymax %f\n", clip->viewport_ymax);
170}
171
172static void dump_sf_state(struct brw_context *brw, uint32_t offset)
173{
174   const char *name = "SF_STATE";
175   struct brw_sf_unit_state *sf = brw->batch.bo->virtual + offset;
176
177   batch_out(brw, name, offset, 0, "thread0\n");
178   batch_out(brw, name, offset, 1, "thread1\n");
179   batch_out(brw, name, offset, 2, "thread2\n");
180   batch_out(brw, name, offset, 3, "thread3\n");
181   batch_out(brw, name, offset, 4, "thread4: %d threads\n",
182	     sf->thread4.max_threads + 1);
183   batch_out(brw, name, offset, 5, "sf5: viewport offset\n");
184   batch_out(brw, name, offset, 6, "sf6\n");
185   batch_out(brw, name, offset, 7, "sf7\n");
186}
187
188static void dump_wm_state(struct brw_context *brw, uint32_t offset)
189{
190   const char *name = "WM_STATE";
191   struct brw_wm_unit_state *wm = brw->batch.bo->virtual + offset;
192
193   batch_out(brw, name, offset, 0, "thread0\n");
194   batch_out(brw, name, offset, 1, "thread1\n");
195   batch_out(brw, name, offset, 2, "thread2\n");
196   batch_out(brw, name, offset, 3, "thread3\n");
197   batch_out(brw, name, offset, 4, "wm4\n");
198   batch_out(brw, name, offset, 5, "wm5: %s%s%s%s%s%s, %d threads\n",
199	     wm->wm5.enable_8_pix ? "8pix" : "",
200	     wm->wm5.enable_16_pix ? "16pix" : "",
201	     wm->wm5.program_uses_depth ? ", uses depth" : "",
202	     wm->wm5.program_computes_depth ? ", computes depth" : "",
203	     wm->wm5.program_uses_killpixel ? ", kills" : "",
204	     wm->wm5.thread_dispatch_enable ? "" : ", no dispatch",
205	     wm->wm5.max_threads + 1);
206   batch_out(brw, name, offset, 6, "depth offset constant %f\n",
207	     wm->global_depth_offset_constant);
208   batch_out(brw, name, offset, 7, "depth offset scale %f\n",
209	     wm->global_depth_offset_scale);
210   batch_out(brw, name, offset, 8, "wm8: kernel 1 (gen5+)\n");
211   batch_out(brw, name, offset, 9, "wm9: kernel 2 (gen5+)\n");
212   batch_out(brw, name, offset, 10, "wm10: kernel 3 (gen5+)\n");
213}
214
215static void dump_surface_state(struct brw_context *brw, uint32_t offset)
216{
217   const char *name = "SURF";
218   uint32_t *surf = brw->batch.bo->virtual + offset;
219
220   batch_out(brw, name, offset, 0, "%s %s\n",
221	     get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
222             isl_format_get_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)));
223   batch_out(brw, name, offset, 1, "offset\n");
224   batch_out(brw, name, offset, 2, "%dx%d size, %d mips\n",
225	     GET_FIELD(surf[2], BRW_SURFACE_WIDTH) + 1,
226	     GET_FIELD(surf[2], BRW_SURFACE_HEIGHT) + 1,
227	     GET_FIELD(surf[2], BRW_SURFACE_LOD));
228   batch_out(brw, name, offset, 3, "pitch %d, %s tiled\n",
229	     GET_FIELD(surf[3], BRW_SURFACE_PITCH) + 1,
230	     (surf[3] & BRW_SURFACE_TILED) ?
231	     ((surf[3] & BRW_SURFACE_TILED_Y) ? "Y" : "X") : "not");
232   batch_out(brw, name, offset, 4, "mip base %d\n",
233	     GET_FIELD(surf[4], BRW_SURFACE_MIN_LOD));
234   batch_out(brw, name, offset, 5, "x,y offset: %d,%d\n",
235	     GET_FIELD(surf[5], BRW_SURFACE_X_OFFSET),
236	     GET_FIELD(surf[5], BRW_SURFACE_Y_OFFSET));
237}
238
239static void dump_gen7_surface_state(struct brw_context *brw, uint32_t offset)
240{
241   const char *name = "SURF";
242   uint32_t *surf = brw->batch.bo->virtual + offset;
243
244   batch_out(brw, name, offset, 0, "%s %s %s\n",
245             get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
246             isl_format_get_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)),
247             (surf[0] & GEN7_SURFACE_IS_ARRAY) ? "array" : "");
248   batch_out(brw, name, offset, 1, "offset\n");
249   batch_out(brw, name, offset, 2, "%dx%d size, %d mips, %d slices\n",
250             GET_FIELD(surf[2], GEN7_SURFACE_WIDTH) + 1,
251             GET_FIELD(surf[2], GEN7_SURFACE_HEIGHT) + 1,
252             surf[5] & INTEL_MASK(3, 0),
253             GET_FIELD(surf[3], BRW_SURFACE_DEPTH) + 1);
254   batch_out(brw, name, offset, 3, "pitch %d, %stiled\n",
255	     (surf[3] & INTEL_MASK(17, 0)) + 1,
256             (surf[0] & (1 << 14)) ? "" : "not ");
257   batch_out(brw, name, offset, 4, "min array element %d, array extent %d\n",
258             GET_FIELD(surf[4], GEN7_SURFACE_MIN_ARRAY_ELEMENT),
259             GET_FIELD(surf[4], GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT) + 1);
260   batch_out(brw, name, offset, 5, "mip base %d\n",
261             GET_FIELD(surf[5], GEN7_SURFACE_MIN_LOD));
262   batch_out(brw, name, offset, 6, "x,y offset: %d,%d\n",
263             GET_FIELD(surf[5], BRW_SURFACE_X_OFFSET),
264             GET_FIELD(surf[5], BRW_SURFACE_Y_OFFSET));
265   batch_out(brw, name, offset, 7, "\n");
266}
267
268static float q_to_float(uint32_t data, int integer_end, int integer_start,
269                        int fractional_end, int fractional_start)
270{
271   /* Convert the number to floating point. */
272   float n = GET_BITS(data, integer_start, fractional_end);
273
274   /* Multiply by 2^-n */
275   return n * exp2(-(fractional_end - fractional_start + 1));
276}
277
278static void
279dump_gen8_surface_state(struct brw_context *brw, uint32_t offset, int index)
280{
281   uint32_t *surf = brw->batch.bo->virtual + offset;
282   int aux_mode = surf[6] & INTEL_MASK(2, 0);
283   const char *aux_str;
284   char *name;
285
286   if (brw->gen >= 9 && (aux_mode == 1 || aux_mode == 5)) {
287      bool msrt = GET_BITS(surf[4], 5, 3) > 0;
288      bool compression = GET_FIELD(surf[7], GEN9_SURFACE_RT_COMPRESSION) == 1;
289      aux_str = ralloc_asprintf(NULL, "AUX_CCS_%c (%s, MULTISAMPLE_COUNT%c1)",
290                                (aux_mode == 1) ? 'D' : 'E',
291                                compression ? "Compressed RT" : "Uncompressed",
292                                msrt ? '>' : '=');
293   } else {
294      static const char *surface_aux_mode[] = { "AUX_NONE", "AUX_MCS",
295                                                "AUX_APPEND", "AUX_HIZ",
296                                                "RSVD", "RSVD"};
297      aux_str = ralloc_asprintf(NULL, "%s", surface_aux_mode[aux_mode]);
298   }
299
300   name = ralloc_asprintf(NULL, "SURF%03d", index);
301   batch_out(brw, name, offset, 0, "%s %s %s VALIGN%d HALIGN%d %s\n",
302             get_965_surfacetype(GET_FIELD(surf[0], BRW_SURFACE_TYPE)),
303             isl_format_get_name(GET_FIELD(surf[0], BRW_SURFACE_FORMAT)),
304             (surf[0] & GEN7_SURFACE_IS_ARRAY) ? "array" : "",
305             1 << (GET_BITS(surf[0], 17, 16) + 1), /* VALIGN */
306             1 << (GET_BITS(surf[0], 15, 14) + 1), /* HALIGN */
307             surface_tiling[GET_BITS(surf[0], 13, 12)]);
308   batch_out(brw, name, offset, 1, "MOCS: 0x%x Base MIP: %.1f (%u mips) Surface QPitch: %d\n",
309             GET_FIELD(surf[1], GEN8_SURFACE_MOCS),
310             q_to_float(surf[1], 23, 20, 19, 19),
311             surf[5] & INTEL_MASK(3, 0),
312             GET_FIELD(surf[1], GEN8_SURFACE_QPITCH) << 2);
313   batch_out(brw, name, offset, 2, "%dx%d [%s]\n",
314             GET_FIELD(surf[2], GEN7_SURFACE_WIDTH) + 1,
315             GET_FIELD(surf[2], GEN7_SURFACE_HEIGHT) + 1,
316             aux_str);
317   batch_out(brw, name, offset, 3, "%d slices (depth), pitch: %d\n",
318             GET_FIELD(surf[3], BRW_SURFACE_DEPTH) + 1,
319             (surf[3] & INTEL_MASK(17, 0)) + 1);
320   batch_out(brw, name, offset, 4, "min array element: %d, array extent %d, MULTISAMPLE_%d\n",
321             GET_FIELD(surf[4], GEN7_SURFACE_MIN_ARRAY_ELEMENT),
322             GET_FIELD(surf[4], GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT) + 1,
323             1 << GET_BITS(surf[4], 5, 3));
324   batch_out(brw, name, offset, 5, "x,y offset: %d,%d, min LOD: %d,"
325             " tr_mode (gen9+): %d, mip tail (gen9+): %d\n",
326             GET_FIELD(surf[5], BRW_SURFACE_X_OFFSET),
327             GET_FIELD(surf[5], BRW_SURFACE_Y_OFFSET),
328             GET_FIELD(surf[5], GEN7_SURFACE_MIN_LOD),
329             GET_FIELD(surf[5], GEN9_SURFACE_TRMODE),
330             GET_FIELD(surf[5], GEN9_SURFACE_MIP_TAIL_START_LOD));
331   batch_out(brw, name, offset, 6, "AUX pitch: %d qpitch: %d\n",
332             GET_FIELD(surf[6], GEN8_SURFACE_AUX_QPITCH) << 2,
333             GET_FIELD(surf[6], GEN8_SURFACE_AUX_PITCH) << 2);
334   if (brw->gen >= 9) {
335      batch_out(brw, name, offset, 7, "Clear color: R(%x)G(%x)B(%x)A(%x)\n",
336                surf[12], surf[13], surf[14], surf[15]);
337   } else {
338      batch_out(brw, name, offset, 7, "Clear color: %c%c%c%c\n",
339                GET_BITS(surf[7], 31, 31) ? 'R' : '-',
340                GET_BITS(surf[7], 30, 30) ? 'G' : '-',
341                GET_BITS(surf[7], 29, 29) ? 'B' : '-',
342                GET_BITS(surf[7], 28, 28) ? 'A' : '-');
343   }
344
345   for (int i = 8; i < 12; i++)
346      batch_out(brw, name, offset, i, "0x%08x\n", surf[i]);
347
348   ralloc_free((void *)aux_str);
349   ralloc_free(name);
350}
351
352static void
353dump_sdc(struct brw_context *brw, uint32_t offset)
354{
355   const char *name = "SDC";
356
357   if (brw->gen >= 5 && brw->gen <= 6) {
358      struct gen5_sampler_default_color *sdc = (brw->batch.bo->virtual +
359                                                offset);
360      batch_out(brw, name, offset, 0, "unorm rgba\n");
361      batch_out(brw, name, offset, 1, "r %f\n", sdc->f[0]);
362      batch_out(brw, name, offset, 2, "b %f\n", sdc->f[1]);
363      batch_out(brw, name, offset, 3, "g %f\n", sdc->f[2]);
364      batch_out(brw, name, offset, 4, "a %f\n", sdc->f[3]);
365      batch_out(brw, name, offset, 5, "half float rg\n");
366      batch_out(brw, name, offset, 6, "half float ba\n");
367      batch_out(brw, name, offset, 7, "u16 rg\n");
368      batch_out(brw, name, offset, 8, "u16 ba\n");
369      batch_out(brw, name, offset, 9, "s16 rg\n");
370      batch_out(brw, name, offset, 10, "s16 ba\n");
371      batch_out(brw, name, offset, 11, "s8 rgba\n");
372   } else {
373      float *sdc = brw->batch.bo->virtual + offset;
374      batch_out(brw, name, offset, 0, "r %f\n", sdc[0]);
375      batch_out(brw, name, offset, 1, "g %f\n", sdc[1]);
376      batch_out(brw, name, offset, 2, "b %f\n", sdc[2]);
377      batch_out(brw, name, offset, 3, "a %f\n", sdc[3]);
378   }
379}
380
381static void dump_sampler_state(struct brw_context *brw,
382			       uint32_t offset, uint32_t size)
383{
384   unsigned i;
385   uint32_t *samp = brw->batch.bo->virtual + offset;
386
387   for (i = 0; i < size / 16; i++) {
388      char name[20];
389
390      sprintf(name, "WM SAMP%u", i);
391      batch_out(brw, name, offset, 0, "filtering\n");
392      batch_out(brw, name, offset, 1, "wrapping, lod\n");
393      batch_out(brw, name, offset, 2, "default color pointer\n");
394      batch_out(brw, name, offset, 3, "chroma key, aniso\n");
395
396      samp += 4;
397      offset += 4 * sizeof(uint32_t);
398   }
399}
400
401static void gen7_dump_sampler_state(struct brw_context *brw,
402                                    uint32_t offset, uint32_t size)
403{
404   const uint32_t *samp = brw->batch.bo->virtual + offset;
405   char name[20];
406
407   for (int i = 0; i < size / 16; i++) {
408      sprintf(name, "SAMPLER_STATE %d", i);
409      batch_out(brw, name, offset, i,
410                "Disabled = %s, Base Mip: %u.%u, Mip/Mag/Min Filter: %s/%s/%s, LOD Bias: %d.%d\n",
411                GET_BITS(samp[0], 31, 31) ? "yes" : "no",
412                GET_BITS(samp[0], 26, 23),
413                GET_BITS(samp[0], 22, 22),
414                sampler_mip_filter[GET_FIELD(samp[0], BRW_SAMPLER_MIP_FILTER)],
415                sampler_mag_filter[GET_FIELD(samp[0], BRW_SAMPLER_MAG_FILTER)],
416                /* min filter defs are the same as mag */
417                sampler_mag_filter[GET_FIELD(samp[0], BRW_SAMPLER_MIN_FILTER)],
418                GET_BITS(samp[0], 13, 10),
419                GET_BITS(samp[0], 9, 1)
420               );
421      batch_out(brw, name, offset, i+1, "Min LOD: %u.%u, Max LOD: %u.%u\n",
422                GET_BITS(samp[1], 31, 28),
423                GET_BITS(samp[1], 27, 20),
424                GET_BITS(samp[1], 19, 16),
425                GET_BITS(samp[1], 15, 8)
426               );
427      batch_out(brw, name, offset, i+2, "Border Color\n"); /* FINISHME: gen8+ */
428      batch_out(brw, name, offset, i+3, "Max aniso: RATIO %d:1, TC[XYZ] Address Control: %s|%s|%s, %snormalized coords\n",
429                (GET_FIELD(samp[3], BRW_SAMPLER_MAX_ANISOTROPY) + 1) * 2,
430                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCX_WRAP_MODE)],
431                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCY_WRAP_MODE)],
432                sampler_addr_mode[GET_FIELD(samp[3], BRW_SAMPLER_TCZ_WRAP_MODE)],
433                (samp[3] & GEN7_SAMPLER_NON_NORMALIZED_COORDINATES) ? "non-" : ""
434               );
435
436      samp += 4;
437      offset += 4 * sizeof(uint32_t);
438   }
439}
440
441static void dump_sf_viewport_state(struct brw_context *brw,
442				   uint32_t offset)
443{
444   const char *name = "SF VP";
445   struct brw_sf_viewport *vp = brw->batch.bo->virtual + offset;
446
447   assert(brw->gen < 7);
448
449   batch_out(brw, name, offset, 0, "m00 = %f\n", vp->viewport.m00);
450   batch_out(brw, name, offset, 1, "m11 = %f\n", vp->viewport.m11);
451   batch_out(brw, name, offset, 2, "m22 = %f\n", vp->viewport.m22);
452   batch_out(brw, name, offset, 3, "m30 = %f\n", vp->viewport.m30);
453   batch_out(brw, name, offset, 4, "m31 = %f\n", vp->viewport.m31);
454   batch_out(brw, name, offset, 5, "m32 = %f\n", vp->viewport.m32);
455
456   batch_out(brw, name, offset, 6, "top left = %d,%d\n",
457	     vp->scissor.xmin, vp->scissor.ymin);
458   batch_out(brw, name, offset, 7, "bottom right = %d,%d\n",
459	     vp->scissor.xmax, vp->scissor.ymax);
460}
461
462static void dump_clip_viewport_state(struct brw_context *brw,
463				     uint32_t offset)
464{
465   const char *name = "CLIP VP";
466   struct brw_clipper_viewport *vp = brw->batch.bo->virtual + offset;
467
468   assert(brw->gen < 7);
469
470   batch_out(brw, name, offset, 0, "xmin = %f\n", vp->xmin);
471   batch_out(brw, name, offset, 1, "xmax = %f\n", vp->xmax);
472   batch_out(brw, name, offset, 2, "ymin = %f\n", vp->ymin);
473   batch_out(brw, name, offset, 3, "ymax = %f\n", vp->ymax);
474}
475
476static void dump_sf_clip_viewport_state(struct brw_context *brw,
477					uint32_t offset)
478{
479   const char *name = "SF_CLIP VP";
480   struct gen7_sf_clip_viewport *vp = brw->batch.bo->virtual + offset;
481
482   assert(brw->gen >= 7);
483
484   batch_out(brw, name, offset, 0, "m00 = %f\n", vp->viewport.m00);
485   batch_out(brw, name, offset, 1, "m11 = %f\n", vp->viewport.m11);
486   batch_out(brw, name, offset, 2, "m22 = %f\n", vp->viewport.m22);
487   batch_out(brw, name, offset, 3, "m30 = %f\n", vp->viewport.m30);
488   batch_out(brw, name, offset, 4, "m31 = %f\n", vp->viewport.m31);
489   batch_out(brw, name, offset, 5, "m32 = %f\n", vp->viewport.m32);
490   batch_out(brw, name, offset, 8, "guardband xmin = %f\n", vp->guardband.xmin);
491   batch_out(brw, name, offset, 9, "guardband xmax = %f\n", vp->guardband.xmax);
492   batch_out(brw, name, offset, 9, "guardband ymin = %f\n", vp->guardband.ymin);
493   batch_out(brw, name, offset, 10, "guardband ymax = %f\n", vp->guardband.ymax);
494   if (brw->gen >= 8) {
495      float *cc_vp = brw->batch.bo->virtual + offset;
496      batch_out(brw, name, offset, 12, "Min extents: %.2fx%.2f\n",
497                cc_vp[12], cc_vp[14]);
498      batch_out(brw, name, offset, 14, "Max extents: %.2fx%.2f\n",
499                cc_vp[13], cc_vp[15]);
500   }
501}
502
503
504static void dump_cc_viewport_state(struct brw_context *brw, uint32_t offset)
505{
506   const char *name = "CC VP";
507   struct brw_cc_viewport *vp = brw->batch.bo->virtual + offset;
508
509   batch_out(brw, name, offset, 0, "min_depth = %f\n", vp->min_depth);
510   batch_out(brw, name, offset, 1, "max_depth = %f\n", vp->max_depth);
511}
512
513static void dump_depth_stencil_state(struct brw_context *brw, uint32_t offset)
514{
515   const char *name = "D_S";
516   struct gen6_depth_stencil_state *ds = brw->batch.bo->virtual + offset;
517
518   batch_out(brw, name, offset, 0,
519	     "stencil %sable, func %d, write %sable\n",
520	     ds->ds0.stencil_enable ? "en" : "dis",
521	     ds->ds0.stencil_func,
522	     ds->ds0.stencil_write_enable ? "en" : "dis");
523   batch_out(brw, name, offset, 1,
524	     "stencil test mask 0x%x, write mask 0x%x\n",
525	     ds->ds1.stencil_test_mask, ds->ds1.stencil_write_mask);
526   batch_out(brw, name, offset, 2,
527	     "depth test %sable, func %d, write %sable\n",
528	     ds->ds2.depth_test_enable ? "en" : "dis",
529	     ds->ds2.depth_test_func,
530	     ds->ds2.depth_write_enable ? "en" : "dis");
531}
532
533static void dump_cc_state_gen4(struct brw_context *brw, uint32_t offset)
534{
535   const char *name = "CC";
536
537   batch_out(brw, name, offset, 0, "cc0\n");
538   batch_out(brw, name, offset, 1, "cc1\n");
539   batch_out(brw, name, offset, 2, "cc2\n");
540   batch_out(brw, name, offset, 3, "cc3\n");
541   batch_out(brw, name, offset, 4, "cc4: viewport offset\n");
542   batch_out(brw, name, offset, 5, "cc5\n");
543   batch_out(brw, name, offset, 6, "cc6\n");
544   batch_out(brw, name, offset, 7, "cc7\n");
545}
546
547static void dump_cc_state_gen6(struct brw_context *brw, uint32_t offset)
548{
549   const char *name = "CC";
550   struct gen6_color_calc_state *cc = brw->batch.bo->virtual + offset;
551
552   batch_out(brw, name, offset, 0,
553	     "alpha test format %s, round disable %d, stencil ref %d, "
554	     "bf stencil ref %d\n",
555	     cc->cc0.alpha_test_format ? "FLOAT32" : "UNORM8",
556	     cc->cc0.round_disable,
557	     cc->cc0.stencil_ref,
558	     cc->cc0.bf_stencil_ref);
559   batch_out(brw, name, offset, 1, "\n");
560   batch_out(brw, name, offset, 2, "constant red %f\n", cc->constant_r);
561   batch_out(brw, name, offset, 3, "constant green %f\n", cc->constant_g);
562   batch_out(brw, name, offset, 4, "constant blue %f\n", cc->constant_b);
563   batch_out(brw, name, offset, 5, "constant alpha %f\n", cc->constant_a);
564}
565
566static void dump_blend_state(struct brw_context *brw, uint32_t offset)
567{
568   const char *name = "BLEND";
569
570   batch_out(brw, name, offset, 0, "\n");
571   batch_out(brw, name, offset, 1, "\n");
572}
573
574static void
575gen8_dump_blend_state(struct brw_context *brw, uint32_t offset, uint32_t size)
576{
577   const uint32_t *blend = brw->batch.bo->virtual + offset;
578   const char *logicop[] =
579   {
580        "LOGICOP_CLEAR (BLACK)",
581        "LOGICOP_NOR",
582        "LOGICOP_AND_INVERTED",
583        "LOGICOP_COPY_INVERTED",
584        "LOGICOP_AND_REVERSE",
585        "LOGICOP_INVERT",
586        "LOGICOP_XOR",
587        "LOGICOP_NAND",
588        "LOGICOP_AND",
589        "LOGICOP_EQUIV",
590        "LOGICOP_NOOP",
591        "LOGICOP_OR_INVERTED",
592        "LOGICOP_COPY",
593        "LOGICOP_OR_REVERSE",
594        "LOGICOP_OR",
595        "LOGICOP_SET (WHITE)"
596   };
597
598   const char *blend_function[] =
599   { "ADD", "SUBTRACT", "REVERSE_SUBTRACT", "MIN", "MAX};" };
600
601   const char *blend_factor[0x1b] =
602   {
603      "RSVD",
604      "ONE",
605      "SRC_COLOR", "SRC_ALPHA",
606      "DST_ALPHA", "DST_COLOR",
607      "SRC_ALPHA_SATURATE",
608      "CONST_COLOR", "CONST_ALPHA",
609      "SRC1_COLOR", "SRC1_ALPHA",
610      "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD",
611      "ZERO",
612      "INV_SRC_COLOR", "INV_SRC_ALPHA",
613      "INV_DST_ALPHA", "INV_DST_COLOR",
614      "RSVD",
615      "INV_CONST_COLOR", "INV_CONST_ALPHA",
616      "INV_SRC1_COLOR", "INV_SRC1_ALPHA"
617   };
618
619   batch_out(brw, "BLEND", offset, 0, "Alpha blend/test\n");
620
621   if (((size) % 2) != 0)
622      fprintf(stderr, "Invalid blend state size %d\n", size);
623
624   for (int i = 1; i < size / 4; i += 2) {
625      char name[sizeof("BLEND_ENTRYXXX")];
626      sprintf(name, "BLEND_ENTRY%02d", (i - 1) / 2);
627      if (blend[i + 1] & GEN8_BLEND_LOGIC_OP_ENABLE) {
628         batch_out(brw, name, offset, i + 1, "%s\n",
629                   logicop[GET_FIELD(blend[i + 1],
630                                     GEN8_BLEND_LOGIC_OP_FUNCTION)]);
631      } else if (blend[i] & GEN8_BLEND_COLOR_BUFFER_BLEND_ENABLE) {
632         batch_out64(brw, name, offset, i,
633                   "\n\t\t\tColor Buffer Blend factor %s,%s,%s,%s (src,dst,src alpha, dst alpha)"
634                   "\n\t\t\tfunction %s,%s (color, alpha), Disables: %c%c%c%c\n",
635                   blend_factor[GET_FIELD(blend[i],
636                                          GEN8_BLEND_SRC_BLEND_FACTOR)],
637                   blend_factor[GET_FIELD(blend[i],
638                                          GEN8_BLEND_DST_BLEND_FACTOR)],
639                   blend_factor[GET_FIELD(blend[i],
640                                          GEN8_BLEND_SRC_ALPHA_BLEND_FACTOR)],
641                   blend_factor[GET_FIELD(blend[i],
642                                          GEN8_BLEND_DST_ALPHA_BLEND_FACTOR)],
643                   blend_function[GET_FIELD(blend[i],
644                                            GEN8_BLEND_COLOR_BLEND_FUNCTION)],
645                   blend_function[GET_FIELD(blend[i],
646                                            GEN8_BLEND_ALPHA_BLEND_FUNCTION)],
647                   blend[i] & GEN8_BLEND_WRITE_DISABLE_RED ? 'R' : '-',
648                   blend[i] & GEN8_BLEND_WRITE_DISABLE_GREEN ? 'G' : '-',
649                   blend[i] & GEN8_BLEND_WRITE_DISABLE_BLUE ? 'B' : '-',
650                   blend[i] & GEN8_BLEND_WRITE_DISABLE_ALPHA ? 'A' : '-'
651                   );
652      } else if (!blend[i] && (blend[i + 1] == 0xb)) {
653         batch_out64(brw, name, offset, i, "NOP blend state\n");
654      } else {
655         batch_out64(brw, name, offset, i, "????\n");
656      }
657   }
658}
659
660static void
661dump_scissor(struct brw_context *brw, uint32_t offset)
662{
663   const char *name = "SCISSOR";
664   struct gen6_scissor_rect *scissor = brw->batch.bo->virtual + offset;
665
666   batch_out(brw, name, offset, 0, "xmin %d, ymin %d\n",
667	     scissor->xmin, scissor->ymin);
668   batch_out(brw, name, offset, 1, "xmax %d, ymax %d\n",
669	     scissor->xmax, scissor->ymax);
670}
671
672static void
673dump_vs_constants(struct brw_context *brw, uint32_t offset, uint32_t size)
674{
675   const char *name = "VS_CONST";
676   uint32_t *as_uint = brw->batch.bo->virtual + offset;
677   float *as_float = brw->batch.bo->virtual + offset;
678   int i;
679
680   for (i = 0; i < size / 4; i += 4) {
681      batch_out(brw, name, offset, i, "%3d: (% f % f % f % f) (0x%08x 0x%08x 0x%08x 0x%08x)\n",
682		i / 4,
683		as_float[i], as_float[i + 1], as_float[i + 2], as_float[i + 3],
684		as_uint[i], as_uint[i + 1], as_uint[i + 2], as_uint[i + 3]);
685   }
686}
687
688static void
689dump_wm_constants(struct brw_context *brw, uint32_t offset, uint32_t size)
690{
691   const char *name = "WM_CONST";
692   uint32_t *as_uint = brw->batch.bo->virtual + offset;
693   float *as_float = brw->batch.bo->virtual + offset;
694   int i;
695
696   for (i = 0; i < size / 4; i += 4) {
697      batch_out(brw, name, offset, i, "%3d: (% f % f % f % f) (0x%08x 0x%08x 0x%08x 0x%08x)\n",
698		i / 4,
699		as_float[i], as_float[i + 1], as_float[i + 2], as_float[i + 3],
700		as_uint[i], as_uint[i + 1], as_uint[i + 2], as_uint[i + 3]);
701   }
702}
703
704static void dump_binding_table(struct brw_context *brw, uint32_t offset,
705			       uint32_t size)
706{
707   char name[20];
708   int i;
709   uint32_t *data = brw->batch.bo->virtual + offset;
710
711   for (i = 0; i < size / 4; i++) {
712      if (data[i] == 0)
713	 continue;
714
715      sprintf(name, "BIND%d", i);
716      batch_out(brw, name, offset, i, "surface state address\n");
717   }
718}
719
720static void
721dump_state_batch(struct brw_context *brw)
722{
723   int i;
724
725   for (i = 0; i < brw->state_batch_count; i++) {
726      uint32_t offset = brw->state_batch_list[i].offset;
727      uint32_t size = brw->state_batch_list[i].size;
728
729      switch (brw->state_batch_list[i].type) {
730      case AUB_TRACE_VS_STATE:
731	 dump_vs_state(brw, offset);
732	 break;
733      case AUB_TRACE_GS_STATE:
734	 dump_gs_state(brw, offset);
735	 break;
736      case AUB_TRACE_CLIP_STATE:
737	 dump_clip_state(brw, offset);
738	 break;
739      case AUB_TRACE_SF_STATE:
740	 dump_sf_state(brw, offset);
741	 break;
742      case AUB_TRACE_WM_STATE:
743	 dump_wm_state(brw, offset);
744	 break;
745      case AUB_TRACE_CLIP_VP_STATE:
746	 dump_clip_viewport_state(brw, offset);
747	 break;
748      case AUB_TRACE_SF_VP_STATE:
749	 if (brw->gen >= 7) {
750	    dump_sf_clip_viewport_state(brw, offset);
751	 } else {
752	    dump_sf_viewport_state(brw, offset);
753	 }
754	 break;
755      case AUB_TRACE_CC_VP_STATE:
756	 dump_cc_viewport_state(brw, offset);
757	 break;
758      case AUB_TRACE_DEPTH_STENCIL_STATE:
759	 dump_depth_stencil_state(brw, offset);
760	 break;
761      case AUB_TRACE_CC_STATE:
762	 if (brw->gen >= 6)
763	    dump_cc_state_gen6(brw, offset);
764	 else
765	    dump_cc_state_gen4(brw, offset);
766	 break;
767      case AUB_TRACE_BLEND_STATE:
768         if (brw->gen >= 8)
769            gen8_dump_blend_state(brw, offset, size);
770         else
771            dump_blend_state(brw, offset);
772	 break;
773      case AUB_TRACE_BINDING_TABLE:
774	 dump_binding_table(brw, offset, size);
775	 break;
776      case AUB_TRACE_SURFACE_STATE:
777         if (brw->gen >= 8) {
778            dump_gen8_surface_state(brw, offset,
779                                    brw->state_batch_list[i].index);
780         } else if (brw->gen >= 7) {
781	    dump_gen7_surface_state(brw, offset);
782         } else {
783            dump_surface_state(brw, offset);
784         }
785	 break;
786      case AUB_TRACE_SAMPLER_STATE:
787         if (brw->gen >= 7)
788            gen7_dump_sampler_state(brw, offset, size);
789         else
790            dump_sampler_state(brw, offset, size);
791	 break;
792      case AUB_TRACE_SAMPLER_DEFAULT_COLOR:
793	 dump_sdc(brw, offset);
794	 break;
795      case AUB_TRACE_SCISSOR_STATE:
796	 dump_scissor(brw, offset);
797	 break;
798      case AUB_TRACE_VS_CONSTANTS:
799	 dump_vs_constants(brw, offset, size);
800	 break;
801      case AUB_TRACE_WM_CONSTANTS:
802	 dump_wm_constants(brw, offset, size);
803	 break;
804      default:
805	 break;
806      }
807   }
808}
809
810/**
811 * Print additional debug information associated with the batchbuffer
812 * when DEBUG_BATCH is set.
813 *
814 * For 965, this means mapping the state buffers that would have been referenced
815 * by the batchbuffer and dumping them.
816 *
817 * The buffer offsets printed rely on the buffer containing the last offset
818 * it was validated at.
819 */
820void brw_debug_batch(struct brw_context *brw)
821{
822   drm_intel_bo_map(brw->batch.bo, false);
823   dump_state_batch(brw);
824   drm_intel_bo_unmap(brw->batch.bo);
825
826   if (0)
827      brw_print_program_cache(brw);
828}
829