Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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