Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright (c) 2014 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 
     24 
     25 #include "intel_batchbuffer.h"
     26 #include "intel_fbo.h"
     27 #include "intel_mipmap_tree.h"
     28 
     29 #include "brw_context.h"
     30 #include "brw_state.h"
     31 #include "brw_defines.h"
     32 
     33 #include "main/mtypes.h"
     34 #include "main/fbobject.h"
     35 #include "main/glformats.h"
     36 
     37 void
     38 gen6_emit_depth_stencil_hiz(struct brw_context *brw,
     39                             struct intel_mipmap_tree *depth_mt,
     40                             uint32_t depth_offset, uint32_t depthbuffer_format,
     41                             uint32_t depth_surface_type,
     42                             struct intel_mipmap_tree *stencil_mt,
     43                             bool hiz, bool separate_stencil,
     44                             uint32_t width, uint32_t height,
     45                             uint32_t tile_x, uint32_t tile_y)
     46 {
     47    struct gl_context *ctx = &brw->ctx;
     48    struct gl_framebuffer *fb = ctx->DrawBuffer;
     49    uint32_t surftype;
     50    unsigned int depth = 1;
     51    GLenum gl_target = GL_TEXTURE_2D;
     52    unsigned int lod;
     53    const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt;
     54    const struct intel_renderbuffer *irb = NULL;
     55    const struct gl_renderbuffer *rb = NULL;
     56 
     57    /* Enable the hiz bit if we're doing separate stencil, because it and the
     58     * separate stencil bit must have the same value. From Section 2.11.5.6.1.1
     59     * 3DSTATE_DEPTH_BUFFER, Bit 1.21 "Separate Stencil Enable":
     60     *     [DevIL]: If this field is enabled, Hierarchical Depth Buffer
     61     *     Enable must also be enabled.
     62     *
     63     *     [DevGT]: This field must be set to the same value (enabled or
     64     *     disabled) as Hierarchical Depth Buffer Enable
     65     */
     66    bool enable_hiz_ss = hiz || separate_stencil;
     67 
     68    brw_emit_depth_stall_flushes(brw);
     69 
     70    irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
     71    if (!irb)
     72       irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
     73    rb = (struct gl_renderbuffer*) irb;
     74 
     75    if (rb) {
     76       depth = MAX2(irb->layer_count, 1);
     77       if (rb->TexImage)
     78          gl_target = rb->TexImage->TexObject->Target;
     79    }
     80 
     81    switch (gl_target) {
     82    case GL_TEXTURE_CUBE_MAP_ARRAY:
     83    case GL_TEXTURE_CUBE_MAP:
     84       /* The PRM claims that we should use BRW_SURFACE_CUBE for this
     85        * situation, but experiments show that gl_Layer doesn't work when we do
     86        * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
     87        * equivalent.
     88        */
     89       surftype = BRW_SURFACE_2D;
     90       depth *= 6;
     91       break;
     92    case GL_TEXTURE_3D:
     93       assert(mt);
     94       depth = MAX2(mt->logical_depth0, 1);
     95       /* fallthrough */
     96    default:
     97       surftype = translate_tex_target(gl_target);
     98       break;
     99    }
    100 
    101    const unsigned min_array_element = irb ? irb->mt_layer : 0;
    102 
    103    lod = irb ? irb->mt_level - irb->mt->first_level : 0;
    104 
    105    if (mt) {
    106       width = mt->logical_width0;
    107       height = mt->logical_height0;
    108    }
    109 
    110    BEGIN_BATCH(7);
    111    /* 3DSTATE_DEPTH_BUFFER dw0 */
    112    OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
    113 
    114    /* 3DSTATE_DEPTH_BUFFER dw1 */
    115    OUT_BATCH((depth_mt ? depth_mt->pitch - 1 : 0) |
    116              (depthbuffer_format << 18) |
    117              ((enable_hiz_ss ? 1 : 0) << 21) | /* separate stencil enable */
    118              ((enable_hiz_ss ? 1 : 0) << 22) | /* hiz enable */
    119              (BRW_TILEWALK_YMAJOR << 26) |
    120              ((depth_mt ? depth_mt->tiling != I915_TILING_NONE : 1)
    121               << 27) |
    122              (surftype << 29));
    123 
    124    /* 3DSTATE_DEPTH_BUFFER dw2 */
    125    if (depth_mt) {
    126       OUT_RELOC(depth_mt->bo,
    127 		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
    128 		0);
    129    } else {
    130       OUT_BATCH(0);
    131    }
    132 
    133    /* 3DSTATE_DEPTH_BUFFER dw3 */
    134    OUT_BATCH(((width - 1) << 6) |
    135              ((height - 1) << 19) |
    136              lod << 2);
    137 
    138    /* 3DSTATE_DEPTH_BUFFER dw4 */
    139    OUT_BATCH((depth - 1) << 21 |
    140              min_array_element << 10 |
    141              (depth - 1) << 1);
    142 
    143    /* 3DSTATE_DEPTH_BUFFER dw5 */
    144    OUT_BATCH(0);
    145    assert(tile_x == 0 && tile_y == 0);
    146 
    147    /* 3DSTATE_DEPTH_BUFFER dw6 */
    148    OUT_BATCH(0);
    149 
    150    ADVANCE_BATCH();
    151 
    152    if (hiz || separate_stencil) {
    153       /*
    154        * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate
    155        * stencil enable' and 'hiz enable' bits were set. Therefore we must
    156        * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if
    157        * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted;
    158        * failure to do so causes hangs on gen5 and a stall on gen6.
    159        */
    160 
    161       /* Emit hiz buffer. */
    162       if (hiz) {
    163          assert(depth_mt);
    164          struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_buf->mt;
    165          uint32_t offset = 0;
    166 
    167          if (hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
    168             offset = intel_miptree_get_aligned_offset(
    169                         hiz_mt,
    170                         hiz_mt->level[lod].level_x,
    171                         hiz_mt->level[lod].level_y);
    172          }
    173 
    174 	 BEGIN_BATCH(3);
    175 	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
    176 	 OUT_BATCH(hiz_mt->pitch - 1);
    177 	 OUT_RELOC(hiz_mt->bo,
    178 		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
    179 		   offset);
    180 	 ADVANCE_BATCH();
    181       } else {
    182 	 BEGIN_BATCH(3);
    183 	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
    184 	 OUT_BATCH(0);
    185 	 OUT_BATCH(0);
    186 	 ADVANCE_BATCH();
    187       }
    188 
    189       /* Emit stencil buffer. */
    190       if (separate_stencil) {
    191          uint32_t offset = 0;
    192 
    193          if (stencil_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
    194             if (stencil_mt->format == MESA_FORMAT_S_UINT8) {
    195                /* Note: we can't compute the stencil offset using
    196                 * intel_region_get_aligned_offset(), because stencil_region
    197                 * claims that the region is untiled even though it's W tiled.
    198                 */
    199                offset =
    200                   stencil_mt->level[lod].level_y * stencil_mt->pitch +
    201                   stencil_mt->level[lod].level_x * 64;
    202             } else {
    203                offset = intel_miptree_get_aligned_offset(
    204                            stencil_mt,
    205                            stencil_mt->level[lod].level_x,
    206                            stencil_mt->level[lod].level_y);
    207             }
    208          }
    209 
    210 	 BEGIN_BATCH(3);
    211 	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
    212          /* The stencil buffer has quirky pitch requirements.  From Vol 2a,
    213           * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
    214           *    The pitch must be set to 2x the value computed based on width, as
    215           *    the stencil buffer is stored with two rows interleaved.
    216           */
    217 	 OUT_BATCH(2 * stencil_mt->pitch - 1);
    218 	 OUT_RELOC(stencil_mt->bo,
    219 		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
    220 		   offset);
    221 	 ADVANCE_BATCH();
    222       } else {
    223 	 BEGIN_BATCH(3);
    224 	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
    225 	 OUT_BATCH(0);
    226 	 OUT_BATCH(0);
    227 	 ADVANCE_BATCH();
    228       }
    229    }
    230 
    231    /*
    232     * On Gen >= 6, emit clear params for safety. If using hiz, then clear
    233     * params must be emitted.
    234     *
    235     * From Section 2.11.5.6.4.1 3DSTATE_CLEAR_PARAMS:
    236     *     3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE packet
    237     *     when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
    238     */
    239    BEGIN_BATCH(2);
    240    OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 |
    241              GEN5_DEPTH_CLEAR_VALID |
    242              (2 - 2));
    243    OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
    244    ADVANCE_BATCH();
    245 }
    246