Home | History | Annotate | Download | only in i965
      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 (at) 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 
     38 static const char *sampler_mip_filter[] = {
     39    "NONE",
     40    "NEAREST",
     41    "RSVD",
     42    "LINEAR"
     43 };
     44 
     45 static const char *sampler_mag_filter[] = {
     46    "NEAREST",
     47    "LINEAR",
     48    "ANISOTROPIC",
     49    "FLEXIBLE (GEN8+)",
     50    "RSVD", "RSVD",
     51    "MONO",
     52    "RSVD"
     53 };
     54 
     55 static const char *sampler_addr_mode[] = {
     56    "WRAP",
     57    "MIRROR",
     58    "CLAMP",
     59    "CUBE",
     60    "CLAMP_BORDER",
     61    "MIRROR_ONCE",
     62    "HALF_BORDER"
     63 };
     64 
     65 static const char *surface_tiling[] = {
     66    "LINEAR",
     67    "W-tiled",
     68    "X-tiled",
     69    "Y-tiled"
     70 };
     71 
     72 static void
     73 batch_out(struct brw_context *brw, const char *name, uint32_t offset,
     74 	  int index, char *fmt, ...) PRINTFLIKE(5, 6);
     75 
     76 static void
     77 batch_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 
     90 static void
     91 batch_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 
    109 static const char *
    110 get_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 
    123 static 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 
    138 static 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 
    153 static 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 
    172 static 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 
    188 static 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 
    215 static 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 
    239 static 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 
    268 static 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 
    278 static void
    279 dump_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 
    352 static void
    353 dump_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 
    381 static 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 
    401 static 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 
    441 static 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 
    462 static 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 
    476 static 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 
    504 static 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 
    513 static 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 
    533 static 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 
    547 static 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 
    566 static 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 
    574 static void
    575 gen8_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 
    660 static void
    661 dump_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 
    672 static void
    673 dump_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 
    688 static void
    689 dump_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 
    704 static 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 
    720 static void
    721 dump_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  */
    820 void 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