Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 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. #include "main/mtypes.h"
  24. #include "main/blend.h"
  25. #include "main/samplerobj.h"
  26. #include "main/texformat.h"
  27. #include "program/prog_parameter.h"
  28.  
  29. #include "intel_mipmap_tree.h"
  30. #include "intel_batchbuffer.h"
  31. #include "intel_tex.h"
  32. #include "intel_fbo.h"
  33. #include "intel_buffer_objects.h"
  34.  
  35. #include "brw_context.h"
  36. #include "brw_state.h"
  37. #include "brw_defines.h"
  38. #include "brw_wm.h"
  39.  
  40. /**
  41.  * Convert an swizzle enumeration (i.e. SWIZZLE_X) to one of the Gen7.5+
  42.  * "Shader Channel Select" enumerations (i.e. HSW_SCS_RED)
  43.  */
  44. static unsigned
  45. swizzle_to_scs(GLenum swizzle)
  46. {
  47.    switch (swizzle) {
  48.    case SWIZZLE_X:
  49.       return HSW_SCS_RED;
  50.    case SWIZZLE_Y:
  51.       return HSW_SCS_GREEN;
  52.    case SWIZZLE_Z:
  53.       return HSW_SCS_BLUE;
  54.    case SWIZZLE_W:
  55.       return HSW_SCS_ALPHA;
  56.    case SWIZZLE_ZERO:
  57.       return HSW_SCS_ZERO;
  58.    case SWIZZLE_ONE:
  59.       return HSW_SCS_ONE;
  60.    }
  61.  
  62.    assert(!"Should not get here: invalid swizzle mode");
  63.    return HSW_SCS_ZERO;
  64. }
  65.  
  66. uint32_t
  67. gen7_surface_tiling_mode(uint32_t tiling)
  68. {
  69.    switch (tiling) {
  70.    case I915_TILING_X:
  71.       return GEN7_SURFACE_TILING_X;
  72.    case I915_TILING_Y:
  73.       return GEN7_SURFACE_TILING_Y;
  74.    default:
  75.       return GEN7_SURFACE_TILING_NONE;
  76.    }
  77. }
  78.  
  79.  
  80. uint32_t
  81. gen7_surface_msaa_bits(unsigned num_samples, enum intel_msaa_layout layout)
  82. {
  83.    uint32_t ss4 = 0;
  84.  
  85.    if (num_samples > 4)
  86.       ss4 |= GEN7_SURFACE_MULTISAMPLECOUNT_8;
  87.    else if (num_samples > 1)
  88.       ss4 |= GEN7_SURFACE_MULTISAMPLECOUNT_4;
  89.    else
  90.       ss4 |= GEN7_SURFACE_MULTISAMPLECOUNT_1;
  91.  
  92.    if (layout == INTEL_MSAA_LAYOUT_IMS)
  93.       ss4 |= GEN7_SURFACE_MSFMT_DEPTH_STENCIL;
  94.    else
  95.       ss4 |= GEN7_SURFACE_MSFMT_MSS;
  96.  
  97.    return ss4;
  98. }
  99.  
  100.  
  101. void
  102. gen7_set_surface_mcs_info(struct brw_context *brw,
  103.                           uint32_t *surf,
  104.                           uint32_t surf_offset,
  105.                           const struct intel_mipmap_tree *mcs_mt,
  106.                           bool is_render_target)
  107. {
  108.    /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
  109.     *
  110.     *     "The MCS surface must be stored as Tile Y."
  111.     */
  112.    assert(mcs_mt->region->tiling == I915_TILING_Y);
  113.  
  114.    /* Compute the pitch in units of tiles.  To do this we need to divide the
  115.     * pitch in bytes by 128, since a single Y-tile is 128 bytes wide.
  116.     */
  117.    unsigned pitch_tiles = mcs_mt->region->pitch / 128;
  118.  
  119.    /* The upper 20 bits of surface state DWORD 6 are the upper 20 bits of the
  120.     * GPU address of the MCS buffer; the lower 12 bits contain other control
  121.     * information.  Since buffer addresses are always on 4k boundaries (and
  122.     * thus have their lower 12 bits zero), we can use an ordinary reloc to do
  123.     * the necessary address translation.
  124.     */
  125.    assert ((mcs_mt->region->bo->offset & 0xfff) == 0);
  126.  
  127.    surf[6] = GEN7_SURFACE_MCS_ENABLE |
  128.              SET_FIELD(pitch_tiles - 1, GEN7_SURFACE_MCS_PITCH) |
  129.              mcs_mt->region->bo->offset;
  130.  
  131.    drm_intel_bo_emit_reloc(brw->batch.bo,
  132.                            surf_offset + 6 * 4,
  133.                            mcs_mt->region->bo,
  134.                            surf[6] & 0xfff,
  135.                            is_render_target ? I915_GEM_DOMAIN_RENDER
  136.                            : I915_GEM_DOMAIN_SAMPLER,
  137.                            is_render_target ? I915_GEM_DOMAIN_RENDER : 0);
  138. }
  139.  
  140.  
  141. void
  142. gen7_check_surface_setup(uint32_t *surf, bool is_render_target)
  143. {
  144.    unsigned num_multisamples = surf[4] & INTEL_MASK(5, 3);
  145.    unsigned multisampled_surface_storage_format = surf[4] & (1 << 6);
  146.    unsigned surface_array_spacing = surf[0] & (1 << 10);
  147.    bool is_multisampled = num_multisamples != GEN7_SURFACE_MULTISAMPLECOUNT_1;
  148.  
  149.    (void) surface_array_spacing;
  150.  
  151.    /* From the Ivybridge PRM, Volume 4 Part 1, page 66 (RENDER_SURFACE_STATE
  152.     * dword 0 bit 10 "Surface Array Spacing" Programming Notes):
  153.     *
  154.     *   If Multisampled Surface Storage Format is MSFMT_MSS and Number of
  155.     *   Multisamples is not MULTISAMPLECOUNT_1, this field must be set to
  156.     *   ARYSPC_LOD0.
  157.     */
  158.    if (multisampled_surface_storage_format == GEN7_SURFACE_MSFMT_MSS
  159.        && is_multisampled)
  160.       assert(surface_array_spacing == GEN7_SURFACE_ARYSPC_LOD0);
  161.  
  162.    /* From the Ivybridge PRM, Volume 4 Part 1, page 72 (RENDER_SURFACE_STATE
  163.     * dword 4 bit 6 "Multisampled Surface Storage" Programming Notes):
  164.     *
  165.     *   All multisampled render target surfaces must have this field set to
  166.     *   MSFMT_MSS.
  167.     *
  168.     * But also:
  169.     *
  170.     *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
  171.     */
  172.    if (is_render_target && is_multisampled) {
  173.       assert(multisampled_surface_storage_format == GEN7_SURFACE_MSFMT_MSS);
  174.    }
  175.  
  176.    /* From the Ivybridge PRM, Volume 4 Part 1, page 72 (RENDER_SURFACE_STATE
  177.     * dword 4 bit 6 "Multisampled Surface Storage Format" Errata):
  178.     *
  179.     *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
  180.     *   is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
  181.     *   field must be set to MSFMT_MSS.
  182.     */
  183.    uint32_t width = GET_FIELD(surf[2], GEN7_SURFACE_WIDTH) + 1;
  184.    if (num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 && width >= 8193) {
  185.       assert(multisampled_surface_storage_format == GEN7_SURFACE_MSFMT_MSS);
  186.    }
  187.  
  188.    /* From the Ivybridge PRM, Volume 4 Part 1, page 72 (RENDER_SURFACE_STATE
  189.     * dword 4 bit 6 "Multisampled Surface Storage Format" Errata):
  190.     *
  191.     *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
  192.     *   ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number of
  193.     *   Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is >
  194.     *   8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.This field
  195.     *   must be set to MSFMT_DEPTH_STENCIL if Surface Format is one of the
  196.     *   following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
  197.     *   R24_UNORM_X8_TYPELESS.
  198.     *
  199.     * But also (from the Programming Notes):
  200.     *
  201.     *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
  202.     */
  203.    uint32_t depth = GET_FIELD(surf[3], BRW_SURFACE_DEPTH) + 1;
  204.    uint32_t height = GET_FIELD(surf[2], GEN7_SURFACE_HEIGHT) + 1;
  205.    if (num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 &&
  206.        depth * height > 4194304) {
  207.       assert(multisampled_surface_storage_format ==
  208.              GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
  209.    }
  210.    if (num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_4 &&
  211.        depth * height > 8388608) {
  212.       assert(multisampled_surface_storage_format ==
  213.              GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
  214.    }
  215.    if (is_multisampled) {
  216.       switch (GET_FIELD(surf[0], BRW_SURFACE_FORMAT)) {
  217.       case BRW_SURFACEFORMAT_I24X8_UNORM:
  218.       case BRW_SURFACEFORMAT_L24X8_UNORM:
  219.       case BRW_SURFACEFORMAT_A24X8_UNORM:
  220.       case BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS:
  221.          assert(multisampled_surface_storage_format ==
  222.                 GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
  223.       }
  224.    }
  225. }
  226.  
  227.  
  228. static void
  229. gen7_update_buffer_texture_surface(struct gl_context *ctx,
  230.                                    unsigned unit,
  231.                                    uint32_t *binding_table,
  232.                                    unsigned surf_index)
  233. {
  234.    struct brw_context *brw = brw_context(ctx);
  235.    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
  236.    struct intel_buffer_object *intel_obj =
  237.       intel_buffer_object(tObj->BufferObject);
  238.    drm_intel_bo *bo = intel_obj ? intel_obj->buffer : NULL;
  239.    gl_format format = tObj->_BufferObjectFormat;
  240.  
  241.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  242.                                     8 * 4, 32, &binding_table[surf_index]);
  243.    memset(surf, 0, 8 * 4);
  244.  
  245.    uint32_t surface_format = brw_format_for_mesa_format(format);
  246.    if (surface_format == 0 && format != MESA_FORMAT_RGBA_FLOAT32) {
  247.       _mesa_problem(NULL, "bad format %s for texture buffer\n",
  248.                     _mesa_get_format_name(format));
  249.    }
  250.  
  251.    surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
  252.              surface_format << BRW_SURFACE_FORMAT_SHIFT |
  253.              BRW_SURFACE_RC_READ_WRITE;
  254.  
  255.    if (bo) {
  256.       surf[1] = bo->offset; /* reloc */
  257.  
  258.       drm_intel_bo_emit_reloc(brw->batch.bo,
  259.                               binding_table[surf_index] + 4,
  260.                               bo, 0,
  261.                               I915_GEM_DOMAIN_SAMPLER, 0);
  262.  
  263.       int texel_size = _mesa_get_format_bytes(format);
  264.       int w = intel_obj->Base.Size / texel_size;
  265.  
  266.       /* note that these differ from GEN6 */
  267.       surf[2] = SET_FIELD(w & 0x7f, GEN7_SURFACE_WIDTH) | /* bits 6:0 of size */
  268.                 SET_FIELD((w >> 7) & 0x3fff, GEN7_SURFACE_HEIGHT); /* 20:7 */
  269.       surf[3] = SET_FIELD((w >> 21) & 0x3f, BRW_SURFACE_DEPTH) | /* bits 26:21 */
  270.                 (texel_size - 1);
  271.    }
  272.  
  273.    gen7_check_surface_setup(surf, false /* is_render_target */);
  274. }
  275.  
  276. static void
  277. gen7_update_texture_surface(struct gl_context *ctx,
  278.                             unsigned unit,
  279.                             uint32_t *binding_table,
  280.                             unsigned surf_index)
  281. {
  282.    struct brw_context *brw = brw_context(ctx);
  283.    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
  284.    struct intel_texture_object *intelObj = intel_texture_object(tObj);
  285.    struct intel_mipmap_tree *mt = intelObj->mt;
  286.    struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
  287.    struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
  288.    uint32_t tile_x, tile_y;
  289.    uint8_t mocs = brw->is_haswell ? GEN7_MOCS_L3 : 0;
  290.  
  291.    if (tObj->Target == GL_TEXTURE_BUFFER) {
  292.       gen7_update_buffer_texture_surface(ctx, unit, binding_table, surf_index);
  293.       return;
  294.    }
  295.  
  296.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  297.                                     8 * 4, 32, &binding_table[surf_index]);
  298.    memset(surf, 0, 8 * 4);
  299.  
  300.    uint32_t tex_format = translate_tex_format(brw,
  301.                                               mt->format,
  302.                                               tObj->DepthMode,
  303.                                               sampler->sRGBDecode);
  304.  
  305.    surf[0] = translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
  306.              tex_format << BRW_SURFACE_FORMAT_SHIFT |
  307.              gen7_surface_tiling_mode(mt->region->tiling) |
  308.              BRW_SURFACE_CUBEFACE_ENABLES;
  309.  
  310.    if (mt->align_h == 4)
  311.       surf[0] |= GEN7_SURFACE_VALIGN_4;
  312.    if (mt->align_w == 8)
  313.       surf[0] |= GEN7_SURFACE_HALIGN_8;
  314.  
  315.    if (mt->logical_depth0 > 1 && tObj->Target != GL_TEXTURE_3D)
  316.       surf[0] |= GEN7_SURFACE_IS_ARRAY;
  317.  
  318.    if (mt->array_spacing_lod0)
  319.       surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
  320.  
  321.    surf[1] = mt->region->bo->offset + mt->offset; /* reloc */
  322.    surf[1] += intel_miptree_get_tile_offsets(intelObj->mt, firstImage->Level, 0,
  323.                                              &tile_x, &tile_y);
  324.  
  325.    surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
  326.              SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
  327.    surf[3] = SET_FIELD(mt->logical_depth0 - 1, BRW_SURFACE_DEPTH) |
  328.              ((intelObj->mt->region->pitch) - 1);
  329.  
  330.    surf[4] = gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
  331.  
  332.    assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
  333.    /* Note that the low bits of these fields are missing, so
  334.     * there's the possibility of getting in trouble.
  335.     */
  336.    surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
  337.               (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT |
  338.               SET_FIELD(mocs, GEN7_SURFACE_MOCS) |
  339.               /* mip count */
  340.               (intelObj->_MaxLevel - tObj->BaseLevel));
  341.  
  342.    if (brw->is_haswell) {
  343.       /* Handling GL_ALPHA as a surface format override breaks 1.30+ style
  344.        * texturing functions that return a float, as our code generation always
  345.        * selects the .x channel (which would always be 0).
  346.        */
  347.       const bool alpha_depth = tObj->DepthMode == GL_ALPHA &&
  348.          (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
  349.           firstImage->_BaseFormat == GL_DEPTH_STENCIL);
  350.  
  351.       const int swizzle = unlikely(alpha_depth)
  352.          ? SWIZZLE_XYZW : brw_get_texture_swizzle(ctx, tObj);
  353.  
  354.       surf[7] =
  355.          SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 0)), GEN7_SURFACE_SCS_R) |
  356.          SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 1)), GEN7_SURFACE_SCS_G) |
  357.          SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 2)), GEN7_SURFACE_SCS_B) |
  358.          SET_FIELD(swizzle_to_scs(GET_SWZ(swizzle, 3)), GEN7_SURFACE_SCS_A);
  359.    }
  360.  
  361.    /* Emit relocation to surface contents */
  362.    drm_intel_bo_emit_reloc(brw->batch.bo,
  363.                            binding_table[surf_index] + 4,
  364.                            intelObj->mt->region->bo,
  365.                            surf[1] - intelObj->mt->region->bo->offset,
  366.                            I915_GEM_DOMAIN_SAMPLER, 0);
  367.  
  368.    gen7_check_surface_setup(surf, false /* is_render_target */);
  369. }
  370.  
  371. /**
  372.  * Create the constant buffer surface.  Vertex/fragment shader constants will
  373.  * be read from this buffer with Data Port Read instructions/messages.
  374.  */
  375. static void
  376. gen7_create_constant_surface(struct brw_context *brw,
  377.                              drm_intel_bo *bo,
  378.                              uint32_t offset,
  379.                              uint32_t size,
  380.                              uint32_t *out_offset,
  381.                              bool dword_pitch)
  382. {
  383.    uint32_t stride = dword_pitch ? 4 : 16;
  384.    uint32_t elements = ALIGN(size, stride) / stride;
  385.    const GLint w = elements - 1;
  386.  
  387.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  388.                                     8 * 4, 32, out_offset);
  389.    memset(surf, 0, 8 * 4);
  390.  
  391.    surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
  392.              BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_SURFACE_FORMAT_SHIFT |
  393.              BRW_SURFACE_RC_READ_WRITE;
  394.  
  395.    assert(bo);
  396.    surf[1] = bo->offset + offset; /* reloc */
  397.  
  398.    /* note that these differ from GEN6 */
  399.    surf[2] = SET_FIELD(w & 0x7f, GEN7_SURFACE_WIDTH) |
  400.              SET_FIELD((w >> 7) & 0x3fff, GEN7_SURFACE_HEIGHT);
  401.    surf[3] = SET_FIELD((w >> 21) & 0x3f, BRW_SURFACE_DEPTH) |
  402.              (stride - 1);
  403.  
  404.    if (brw->is_haswell) {
  405.       surf[7] = SET_FIELD(HSW_SCS_RED,   GEN7_SURFACE_SCS_R) |
  406.                 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
  407.                 SET_FIELD(HSW_SCS_BLUE,  GEN7_SURFACE_SCS_B) |
  408.                 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
  409.    }
  410.  
  411.    drm_intel_bo_emit_reloc(brw->batch.bo,
  412.                            *out_offset + 4,
  413.                            bo, offset,
  414.                            I915_GEM_DOMAIN_SAMPLER, 0);
  415.  
  416.    gen7_check_surface_setup(surf, false /* is_render_target */);
  417. }
  418.  
  419. /**
  420.  * Create a surface for shader time.
  421.  */
  422. void
  423. gen7_create_shader_time_surface(struct brw_context *brw, uint32_t *out_offset)
  424. {
  425.    const int w = brw->shader_time.bo->size - 1;
  426.  
  427.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  428.                                     8 * 4, 32, out_offset);
  429.    memset(surf, 0, 8 * 4);
  430.  
  431.    surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
  432.              BRW_SURFACEFORMAT_RAW << BRW_SURFACE_FORMAT_SHIFT |
  433.              BRW_SURFACE_RC_READ_WRITE;
  434.  
  435.    surf[1] = brw->shader_time.bo->offset; /* reloc */
  436.  
  437.    /* note that these differ from GEN6 */
  438.    surf[2] = SET_FIELD(w & 0x7f, GEN7_SURFACE_WIDTH) |
  439.              SET_FIELD((w >> 7) & 0x3fff, GEN7_SURFACE_HEIGHT);
  440.    surf[3] = SET_FIELD((w >> 21) & 0x3f, BRW_SURFACE_DEPTH);
  441.  
  442.    /* Unlike texture or renderbuffer surfaces, we only do untyped operations
  443.     * on the shader_time surface, so there's no need to set HSW channel
  444.     * overrides.
  445.     */
  446.  
  447.    drm_intel_bo_emit_reloc(brw->batch.bo,
  448.                            *out_offset + 4,
  449.                            brw->shader_time.bo, 0,
  450.                            I915_GEM_DOMAIN_SAMPLER, 0);
  451.  
  452.    gen7_check_surface_setup(surf, false /* is_render_target */);
  453. }
  454.  
  455. static void
  456. gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
  457. {
  458.    /* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming
  459.     * Notes):
  460.     *
  461.     *     A null surface is used in instances where an actual surface is not
  462.     *     bound. When a write message is generated to a null surface, no
  463.     *     actual surface is written to. When a read message (including any
  464.     *     sampling engine message) is generated to a null surface, the result
  465.     *     is all zeros. Note that a null surface type is allowed to be used
  466.     *     with all messages, even if it is not specificially indicated as
  467.     *     supported. All of the remaining fields in surface state are ignored
  468.     *     for null surfaces, with the following exceptions: Width, Height,
  469.     *     Depth, LOD, and Render Target View Extent fields must match the
  470.     *     depth buffer’s corresponding state for all render target surfaces,
  471.     *     including null.
  472.     */
  473.    struct gl_context *ctx = &brw->ctx;
  474.  
  475.    /* _NEW_BUFFERS */
  476.    const struct gl_framebuffer *fb = ctx->DrawBuffer;
  477.  
  478.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  479.                                     8 * 4, 32, &brw->wm.surf_offset[unit]);
  480.    memset(surf, 0, 8 * 4);
  481.  
  482.    /* From the Ivybridge PRM, Volume 4, Part 1, page 65,
  483.     * Tiled Surface: Programming Notes:
  484.     * "If Surface Type is SURFTYPE_NULL, this field must be TRUE."
  485.     */
  486.    surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
  487.              BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
  488.              GEN7_SURFACE_TILING_Y;
  489.  
  490.    surf[2] = SET_FIELD(fb->Width - 1, GEN7_SURFACE_WIDTH) |
  491.              SET_FIELD(fb->Height - 1, GEN7_SURFACE_HEIGHT);
  492.  
  493.    gen7_check_surface_setup(surf, true /* is_render_target */);
  494. }
  495.  
  496. /**
  497.  * Sets up a surface state structure to point at the given region.
  498.  * While it is only used for the front/back buffer currently, it should be
  499.  * usable for further buffers when doing ARB_draw_buffer support.
  500.  */
  501. static void
  502. gen7_update_renderbuffer_surface(struct brw_context *brw,
  503.                                  struct gl_renderbuffer *rb,
  504.                                  bool layered,
  505.                                  unsigned int unit)
  506. {
  507.    struct gl_context *ctx = &brw->ctx;
  508.    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
  509.    struct intel_region *region = irb->mt->region;
  510.    uint32_t format;
  511.    /* _NEW_BUFFERS */
  512.    gl_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));
  513.    uint32_t surftype;
  514.    bool is_array = false;
  515.    int depth = MAX2(rb->Depth, 1);
  516.    int min_array_element;
  517.    uint8_t mocs = brw->is_haswell ? GEN7_MOCS_L3 : 0;
  518.    GLenum gl_target = rb->TexImage ?
  519.                          rb->TexImage->TexObject->Target : GL_TEXTURE_2D;
  520.  
  521.    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
  522.                                     8 * 4, 32, &brw->wm.surf_offset[unit]);
  523.    memset(surf, 0, 8 * 4);
  524.  
  525.    intel_miptree_used_for_rendering(irb->mt);
  526.  
  527.    /* Render targets can't use IMS layout */
  528.    assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
  529.  
  530.    assert(brw_render_target_supported(brw, rb));
  531.    format = brw->render_target_format[rb_format];
  532.    if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
  533.       _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
  534.                     __FUNCTION__, _mesa_get_format_name(rb_format));
  535.    }
  536.  
  537.    switch (gl_target) {
  538.    case GL_TEXTURE_CUBE_MAP_ARRAY:
  539.    case GL_TEXTURE_CUBE_MAP:
  540.       surftype = BRW_SURFACE_2D;
  541.       is_array = true;
  542.       depth *= 6;
  543.       break;
  544.    default:
  545.       surftype = translate_tex_target(gl_target);
  546.       is_array = _mesa_tex_target_is_array(gl_target);
  547.       break;
  548.    }
  549.  
  550.    if (layered) {
  551.       min_array_element = 0;
  552.    } else if (irb->mt->num_samples > 1) {
  553.       min_array_element = irb->mt_layer / irb->mt->num_samples;
  554.    } else {
  555.       min_array_element = irb->mt_layer;
  556.    }
  557.  
  558.    surf[0] = surftype << BRW_SURFACE_TYPE_SHIFT |
  559.              format << BRW_SURFACE_FORMAT_SHIFT |
  560.              (irb->mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0
  561.                                           : GEN7_SURFACE_ARYSPC_FULL) |
  562.              gen7_surface_tiling_mode(region->tiling);
  563.  
  564.    if (irb->mt->align_h == 4)
  565.       surf[0] |= GEN7_SURFACE_VALIGN_4;
  566.    if (irb->mt->align_w == 8)
  567.       surf[0] |= GEN7_SURFACE_HALIGN_8;
  568.  
  569.    if (is_array) {
  570.       surf[0] |= GEN7_SURFACE_IS_ARRAY;
  571.    }
  572.  
  573.    surf[1] = region->bo->offset;
  574.  
  575.    assert(brw->has_surface_tile_offset);
  576.  
  577.    surf[5] = SET_FIELD(mocs, GEN7_SURFACE_MOCS) |
  578.              (irb->mt_level - irb->mt->first_level);
  579.  
  580.    surf[2] = SET_FIELD(irb->mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
  581.              SET_FIELD(irb->mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
  582.  
  583.    surf[3] = ((depth - 1) << BRW_SURFACE_DEPTH_SHIFT) |
  584.              (region->pitch - 1);
  585.  
  586.    surf[4] = gen7_surface_msaa_bits(irb->mt->num_samples, irb->mt->msaa_layout) |
  587.              min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
  588.              (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;
  589.  
  590.    if (irb->mt->mcs_mt) {
  591.       gen7_set_surface_mcs_info(brw, surf, brw->wm.surf_offset[unit],
  592.                                 irb->mt->mcs_mt, true /* is RT */);
  593.    }
  594.  
  595.    surf[7] = irb->mt->fast_clear_color_value;
  596.  
  597.    if (brw->is_haswell) {
  598.       surf[7] |= (SET_FIELD(HSW_SCS_RED,   GEN7_SURFACE_SCS_R) |
  599.                   SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
  600.                   SET_FIELD(HSW_SCS_BLUE,  GEN7_SURFACE_SCS_B) |
  601.                   SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A));
  602.    }
  603.  
  604.    drm_intel_bo_emit_reloc(brw->batch.bo,
  605.                            brw->wm.surf_offset[unit] + 4,
  606.                            region->bo,
  607.                            surf[1] - region->bo->offset,
  608.                            I915_GEM_DOMAIN_RENDER,
  609.                            I915_GEM_DOMAIN_RENDER);
  610.  
  611.    gen7_check_surface_setup(surf, true /* is_render_target */);
  612. }
  613.  
  614. void
  615. gen7_init_vtable_surface_functions(struct brw_context *brw)
  616. {
  617.    brw->vtbl.update_texture_surface = gen7_update_texture_surface;
  618.    brw->vtbl.update_renderbuffer_surface = gen7_update_renderbuffer_surface;
  619.    brw->vtbl.update_null_renderbuffer_surface =
  620.       gen7_update_null_renderbuffer_surface;
  621.    brw->vtbl.create_constant_surface = gen7_create_constant_surface;
  622. }
  623.