コード例 #1
0
static dri_bo *
brw_create_texture_surface( struct brw_context *brw,
			    struct brw_surface_key *key )
{
   struct brw_surface_state surf;
   dri_bo *bo;

   memset(&surf, 0, sizeof(surf));

   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
   surf.ss0.surface_type = translate_tex_target(key->target);
   surf.ss0.surface_format = translate_tex_format(key->format,
						  key->internal_format,
						  key->depthmode);

   /* This is ok for all textures with channel width 8bit or less:
    */
/*    surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
   surf.ss1.base_addr = key->bo->offset; /* reloc */

   surf.ss2.mip_count = key->last_level - key->first_level;
   surf.ss2.width = key->width - 1;
   surf.ss2.height = key->height - 1;
   brw_set_surface_tiling(&surf, key->tiling);
   surf.ss3.pitch = (key->pitch * key->cpp) - 1;
   surf.ss3.depth = key->depth - 1;

   surf.ss4.min_lod = 0;
 
   if (key->target == GL_TEXTURE_CUBE_MAP) {
      surf.ss0.cube_pos_x = 1;
      surf.ss0.cube_pos_y = 1;
      surf.ss0.cube_pos_z = 1;
      surf.ss0.cube_neg_x = 1;
      surf.ss0.cube_neg_y = 1;
      surf.ss0.cube_neg_z = 1;
   }

   bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
			 key, sizeof(*key),
			 &key->bo, 1,
			 &surf, sizeof(surf));

   /* Emit relocation to surface contents */
   drm_intel_bo_emit_reloc(bo, offsetof(struct brw_surface_state, ss1),
			   key->bo, 0,
			   I915_GEM_DOMAIN_SAMPLER, 0);

   return bo;
}
コード例 #2
0
ファイル: brw_wm_surface_state.c プロジェクト: Starlink/mesa
static
void brw_update_texture_surface( GLcontext *ctx, 
				 GLuint unit,
				 struct brw_surface_state *surf )
{
   struct intel_context *intel = intel_context(ctx);
   struct brw_context *brw = brw_context(ctx);
   struct gl_texture_object *tObj = brw->attribs.Texture->Unit[unit]._Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];

   memset(surf, 0, sizeof(*surf));

   surf->ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;   
   surf->ss0.surface_type = translate_tex_target(tObj->Target);
   surf->ss0.surface_format = translate_tex_format(firstImage->TexFormat->MesaFormat, tObj->DepthMode);

   /* This is ok for all textures with channel width 8bit or less:
    */
/*    surf->ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */

   /* BRW_NEW_LOCK */
   surf->ss1.base_addr = bmBufferOffset(intel,
					intelObj->mt->region->buffer);

   surf->ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
   surf->ss2.width = firstImage->Width - 1;
   surf->ss2.height = firstImage->Height - 1;

   surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
   surf->ss3.tiled_surface = intelObj->mt->region->tiled; /* always zero */
   surf->ss3.pitch = (intelObj->mt->pitch * intelObj->mt->cpp) - 1;
   surf->ss3.depth = firstImage->Depth - 1;

   surf->ss4.min_lod = 0;
 
   if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
      surf->ss0.cube_pos_x = 1;
      surf->ss0.cube_pos_y = 1;
      surf->ss0.cube_pos_z = 1;
      surf->ss0.cube_neg_x = 1;
      surf->ss0.cube_neg_y = 1;
      surf->ss0.cube_neg_z = 1;
   }
}
コード例 #3
0
ファイル: gen7_misc_state.c プロジェクト: UIKit0/mesa-1
void
gen7_emit_depth_stencil_hiz(struct brw_context *brw,
                            struct intel_mipmap_tree *depth_mt,
                            uint32_t depth_offset, uint32_t depthbuffer_format,
                            uint32_t depth_surface_type,
                            struct intel_mipmap_tree *stencil_mt,
                            bool hiz, bool separate_stencil,
                            uint32_t width, uint32_t height,
                            uint32_t tile_x, uint32_t tile_y)
{
   struct gl_context *ctx = &brw->ctx;
   const uint8_t mocs = GEN7_MOCS_L3;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   uint32_t surftype;
   unsigned int depth = 1;
   unsigned int min_array_element;
   GLenum gl_target = GL_TEXTURE_2D;
   unsigned int lod;
   const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt;
   const struct intel_renderbuffer *irb = NULL;
   const struct gl_renderbuffer *rb = NULL;

   intel_emit_depth_stall_flushes(brw);

   irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
   if (!irb)
      irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
   rb = (struct gl_renderbuffer*) irb;

   if (rb) {
      depth = MAX2(rb->Depth, 1);
      if (rb->TexImage)
         gl_target = rb->TexImage->TexObject->Target;
   }

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      /* The PRM claims that we should use BRW_SURFACE_CUBE for this
       * situation, but experiments show that gl_Layer doesn't work when we do
       * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
       * equivalent.
       */
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   if (fb->Layered || !irb) {
      min_array_element = 0;
   } else if (irb->mt->num_samples > 1) {
      /* Convert physical layer to logical layer. */
      min_array_element = irb->mt_layer / irb->mt->num_samples;
   } else {
      min_array_element = irb->mt_layer;
   }

   lod = irb ? irb->mt_level - irb->mt->first_level : 0;

   if (mt) {
      width = mt->physical_width0;
      height = mt->physical_height0;
   }

   /* _NEW_DEPTH, _NEW_STENCIL, _NEW_BUFFERS */
   BEGIN_BATCH(7);
   /* 3DSTATE_DEPTH_BUFFER dw0 */
   OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));

   /* 3DSTATE_DEPTH_BUFFER dw1 */
   OUT_BATCH((depth_mt ? depth_mt->region->pitch - 1 : 0) |
             (depthbuffer_format << 18) |
             ((hiz ? 1 : 0) << 22) |
             ((stencil_mt != NULL && ctx->Stencil._WriteEnabled) << 27) |
             ((ctx->Depth.Mask != 0) << 28) |
             (surftype << 29));

   /* 3DSTATE_DEPTH_BUFFER dw2 */
   if (depth_mt) {
      OUT_RELOC(depth_mt->region->bo,
	        I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
	        0);
   } else {
      OUT_BATCH(0);
   }

   /* 3DSTATE_DEPTH_BUFFER dw3 */
   OUT_BATCH(((width - 1) << 4) |
             ((height - 1) << 18) |
             lod);

   /* 3DSTATE_DEPTH_BUFFER dw4 */
   OUT_BATCH(((depth - 1) << 21) |
             (min_array_element << 10) |
             mocs);

   /* 3DSTATE_DEPTH_BUFFER dw5 */
   OUT_BATCH(0);

   /* 3DSTATE_DEPTH_BUFFER dw6 */
   OUT_BATCH((depth - 1) << 21);
   ADVANCE_BATCH();

   if (!hiz) {
      BEGIN_BATCH(3);
      OUT_BATCH(GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2));
      OUT_BATCH(0);
      OUT_BATCH(0);
      ADVANCE_BATCH();
   } else {
      struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt;
      BEGIN_BATCH(3);
      OUT_BATCH(GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2));
      OUT_BATCH((mocs << 25) |
                (hiz_mt->region->pitch - 1));
      OUT_RELOC(hiz_mt->region->bo,
                I915_GEM_DOMAIN_RENDER,
                I915_GEM_DOMAIN_RENDER,
                0);
      ADVANCE_BATCH();
   }

   if (stencil_mt == NULL) {
      BEGIN_BATCH(3);
      OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
      OUT_BATCH(0);
      OUT_BATCH(0);
      ADVANCE_BATCH();
   } else {
      const int enabled = brw->is_haswell ? HSW_STENCIL_ENABLED : 0;

      BEGIN_BATCH(3);
      OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
      /* The stencil buffer has quirky pitch requirements.  From the
       * Sandybridge PRM, Volume 2 Part 1, page 329 (3DSTATE_STENCIL_BUFFER
       * dword 1 bits 16:0 - Surface Pitch):
       *
       *    The pitch must be set to 2x the value computed based on width, as
       *    the stencil buffer is stored with two rows interleaved.
       *
       * While the Ivybridge PRM lacks this comment, the BSpec contains the
       * same text, and experiments indicate that this is necessary.
       */
      OUT_BATCH(enabled |
                mocs << 25 |
	        (2 * stencil_mt->region->pitch - 1));
      OUT_RELOC(stencil_mt->region->bo,
	        I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
		0);
      ADVANCE_BATCH();
   }

   BEGIN_BATCH(3);
   OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2));
   OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
   OUT_BATCH(1);
   ADVANCE_BATCH();
}
コード例 #4
0
ファイル: gen6_blorp.c プロジェクト: BNieuwenhuizen/mesa
static void
gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
                                     const struct brw_blorp_params *params)
{
   uint32_t surfwidth, surfheight;
   uint32_t surftype;
   unsigned int depth = MAX2(params->depth.mt->logical_depth0, 1);
   GLenum gl_target = params->depth.mt->target;
   unsigned int lod;

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      /* The PRM claims that we should use BRW_SURFACE_CUBE for this
       * situation, but experiments show that gl_Layer doesn't work when we do
       * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
       * equivalent.
       */
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   const unsigned min_array_element = params->depth.layer;

   lod = params->depth.level - params->depth.mt->first_level;

   if (params->hiz_op != GEN6_HIZ_OP_NONE && lod == 0) {
      /* HIZ ops for lod 0 may set the width & height a little
       * larger to allow the fast depth clear to fit the hardware
       * alignment requirements. (8x4)
       */
      surfwidth = params->depth.width;
      surfheight = params->depth.height;
   } else {
      surfwidth = params->depth.mt->logical_width0;
      surfheight = params->depth.mt->logical_height0;
   }

   /* 3DSTATE_DEPTH_BUFFER */
   {
      brw_emit_depth_stall_flushes(brw);

      BEGIN_BATCH(7);
      /* 3DSTATE_DEPTH_BUFFER dw0 */
      OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));

      /* 3DSTATE_DEPTH_BUFFER dw1 */
      OUT_BATCH((params->depth.mt->pitch - 1) |
                params->depth_format << 18 |
                1 << 21 | /* separate stencil enable */
                1 << 22 | /* hiz enable */
                BRW_TILEWALK_YMAJOR << 26 |
                1 << 27 | /* y-tiled */
                surftype << 29);

      /* 3DSTATE_DEPTH_BUFFER dw2 */
      OUT_RELOC(params->depth.mt->bo,
                I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                0);

      /* 3DSTATE_DEPTH_BUFFER dw3 */
      OUT_BATCH(BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1 |
                (surfwidth - 1) << 6 |
                (surfheight - 1) << 19 |
                lod << 2);

      /* 3DSTATE_DEPTH_BUFFER dw4 */
      OUT_BATCH((depth - 1) << 21 |
                min_array_element << 10 |
                (depth - 1) << 1);

      /* 3DSTATE_DEPTH_BUFFER dw5 */
      OUT_BATCH(0);

      /* 3DSTATE_DEPTH_BUFFER dw6 */
      OUT_BATCH(0);
      ADVANCE_BATCH();
   }

   /* 3DSTATE_HIER_DEPTH_BUFFER */
   {
      struct intel_mipmap_tree *hiz_mt = params->depth.mt->hiz_buf->mt;
      uint32_t offset = 0;

      if (hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
         offset = intel_miptree_get_aligned_offset(hiz_mt,
                                                   hiz_mt->level[lod].level_x,
                                                   hiz_mt->level[lod].level_y,
                                                   false);
      }

      BEGIN_BATCH(3);
      OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
      OUT_BATCH(hiz_mt->pitch - 1);
      OUT_RELOC(hiz_mt->bo,
                I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                offset);
      ADVANCE_BATCH();
   }

   /* 3DSTATE_STENCIL_BUFFER */
   {
      BEGIN_BATCH(3);
      OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
      OUT_BATCH(0);
      OUT_BATCH(0);
      ADVANCE_BATCH();
   }
}
コード例 #5
0
static void
gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
                                     const brw_blorp_params *params)
{
   const uint8_t mocs = GEN7_MOCS_L3;
   uint32_t surfwidth, surfheight;
   uint32_t surftype;
   unsigned int depth = MAX2(params->depth.mt->logical_depth0, 1);
   unsigned int min_array_element;
   GLenum gl_target = params->depth.mt->target;
   unsigned int lod;

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      /* The PRM claims that we should use BRW_SURFACE_CUBE for this
       * situation, but experiments show that gl_Layer doesn't work when we do
       * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
       * equivalent.
       */
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   min_array_element = params->depth.layer;
   if (params->depth.mt->num_samples > 1) {
      /* Convert physical layer to logical layer. */
      min_array_element /= params->depth.mt->num_samples;
   }

   lod = params->depth.level - params->depth.mt->first_level;

   if (params->hiz_op != GEN6_HIZ_OP_NONE && lod == 0) {
      /* HIZ ops for lod 0 may set the width & height a little
       * larger to allow the fast depth clear to fit the hardware
       * alignment requirements. (8x4)
       */
      surfwidth = params->depth.width;
      surfheight = params->depth.height;
   } else {
      surfwidth = params->depth.mt->logical_width0;
      surfheight = params->depth.mt->logical_height0;
   }

   /* 3DSTATE_DEPTH_BUFFER */
   {
      intel_emit_depth_stall_flushes(brw);

      BEGIN_BATCH(7);
      OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
      OUT_BATCH((params->depth.mt->region->pitch - 1) |
                params->depth_format << 18 |
                1 << 22 | /* hiz enable */
                1 << 28 | /* depth write */
                surftype << 29);
      OUT_RELOC(params->depth.mt->region->bo,
                I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                0);
      OUT_BATCH((surfwidth - 1) << 4 |
                (surfheight - 1) << 18 |
                lod);
      OUT_BATCH(((depth - 1) << 21) |
                (min_array_element << 10) |
                mocs);
      OUT_BATCH(0);
      OUT_BATCH((depth - 1) << 21);
      ADVANCE_BATCH();
   }

   /* 3DSTATE_HIER_DEPTH_BUFFER */
   {
      struct intel_region *hiz_region = params->depth.mt->hiz_mt->region;

      BEGIN_BATCH(3);
      OUT_BATCH((GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
      OUT_BATCH((mocs << 25) |
                (hiz_region->pitch - 1));
      OUT_RELOC(hiz_region->bo,
                I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                0);
      ADVANCE_BATCH();
   }

   /* 3DSTATE_STENCIL_BUFFER */
   {
      BEGIN_BATCH(3);
      OUT_BATCH((GEN7_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
      OUT_BATCH(0);
      OUT_BATCH(0);
      ADVANCE_BATCH();
   }
}
コード例 #6
0
/**
 * Sets up a surface state structure to point at the given region.
 * While it is only used for the front/back buffer currently, it should be
 * usable for further buffers when doing ARB_draw_buffer support.
 */
static void
gen6_update_renderbuffer_surface(struct brw_context *brw,
                                 struct gl_renderbuffer *rb,
                                 bool layered,
                                 unsigned int unit)
{
   struct gl_context *ctx = &brw->ctx;
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
   struct intel_mipmap_tree *mt = irb->mt;
   uint32_t *surf;
   uint32_t format = 0;
   /* _NEW_BUFFERS */
   mesa_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));
   uint32_t surftype;
   int depth = MAX2(irb->layer_count, 1);
   const GLenum gl_target =
      rb->TexImage ? rb->TexImage->TexObject->Target : GL_TEXTURE_2D;

   uint32_t surf_index =
      brw->wm.prog_data->binding_table.render_target_start + unit;

   intel_miptree_used_for_rendering(irb->mt);

   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
                          &brw->wm.base.surf_offset[surf_index]);

   format = brw->render_target_format[rb_format];
   if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
      _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
                    __func__, _mesa_get_format_name(rb_format));
   }

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   case GL_TEXTURE_3D:
      depth = MAX2(irb->mt->logical_depth0, 1);
      /* fallthrough */
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   const int min_array_element = layered ? 0 : irb->mt_layer;

   surf[0] = SET_FIELD(surftype, BRW_SURFACE_TYPE) |
             SET_FIELD(format, BRW_SURFACE_FORMAT);

   /* reloc */
   assert(mt->offset % mt->cpp == 0);
   surf[1] = mt->bo->offset64 + mt->offset;

   /* In the gen6 PRM Volume 1 Part 1: Graphics Core, Section 7.18.3.7.1
    * (Surface Arrays For all surfaces other than separate stencil buffer):
    *
    * "[DevSNB] Errata: Sampler MSAA Qpitch will be 4 greater than the value
    *  calculated in the equation above , for every other odd Surface Height
    *  starting from 1 i.e. 1,5,9,13"
    *
    * Since this Qpitch errata only impacts the sampler, we have to adjust the
    * input for the rendering surface to achieve the same qpitch. For the
    * affected heights, we increment the height by 1 for the rendering
    * surface.
    */
   int height0 = irb->mt->logical_height0;
   if (brw->gen == 6 && irb->mt->num_samples > 1 && (height0 % 4) == 1)
      height0++;

   surf[2] = SET_FIELD(mt->logical_width0 - 1, BRW_SURFACE_WIDTH) |
             SET_FIELD(height0 - 1, BRW_SURFACE_HEIGHT) |
             SET_FIELD(irb->mt_level - irb->mt->first_level, BRW_SURFACE_LOD);

   surf[3] = brw_get_surface_tiling_bits(mt->tiling) |
             SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |
             SET_FIELD(mt->pitch - 1, BRW_SURFACE_PITCH);

   surf[4] = brw_get_surface_num_multisamples(mt->num_samples) |
             SET_FIELD(min_array_element, BRW_SURFACE_MIN_ARRAY_ELEMENT) |
             SET_FIELD(depth - 1, BRW_SURFACE_RENDER_TARGET_VIEW_EXTENT);

   surf[5] = (mt->align_h == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0);

   drm_intel_bo_emit_reloc(brw->batch.bo,
			   brw->wm.base.surf_offset[surf_index] + 4,
			   mt->bo,
			   surf[1] - mt->bo->offset64,
			   I915_GEM_DOMAIN_RENDER,
			   I915_GEM_DOMAIN_RENDER);
}
コード例 #7
0
ファイル: gen6_depth_state.c プロジェクト: aphogat/mesa
void
gen6_emit_depth_stencil_hiz(struct brw_context *brw,
                            struct intel_mipmap_tree *depth_mt,
                            uint32_t depth_offset, uint32_t depthbuffer_format,
                            uint32_t depth_surface_type,
                            struct intel_mipmap_tree *stencil_mt,
                            bool hiz, bool separate_stencil,
                            uint32_t width, uint32_t height,
                            uint32_t tile_x, uint32_t tile_y)
{
   struct gl_context *ctx = &brw->ctx;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   uint32_t surftype;
   unsigned int depth = 1;
   GLenum gl_target = GL_TEXTURE_2D;
   unsigned int lod;
   const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt;
   const struct intel_renderbuffer *irb = NULL;
   const struct gl_renderbuffer *rb = NULL;

   /* Enable the hiz bit if we're doing separate stencil, because it and the
    * separate stencil bit must have the same value. From Section 2.11.5.6.1.1
    * 3DSTATE_DEPTH_BUFFER, Bit 1.21 "Separate Stencil Enable":
    *     [DevIL]: If this field is enabled, Hierarchical Depth Buffer
    *     Enable must also be enabled.
    *
    *     [DevGT]: This field must be set to the same value (enabled or
    *     disabled) as Hierarchical Depth Buffer Enable
    */
   bool enable_hiz_ss = hiz || separate_stencil;

   brw_emit_depth_stall_flushes(brw);

   irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
   if (!irb)
      irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
   rb = (struct gl_renderbuffer*) irb;

   if (rb) {
      depth = MAX2(irb->layer_count, 1);
      if (rb->TexImage)
         gl_target = rb->TexImage->TexObject->Target;
   }

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      /* The PRM claims that we should use BRW_SURFACE_CUBE for this
       * situation, but experiments show that gl_Layer doesn't work when we do
       * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
       * equivalent.
       */
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   case GL_TEXTURE_3D:
      assert(mt);
      depth = MAX2(mt->logical_depth0, 1);
      /* fallthrough */
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   const unsigned min_array_element = irb ? irb->mt_layer : 0;

   lod = irb ? irb->mt_level - irb->mt->first_level : 0;

   if (mt) {
      width = mt->logical_width0;
      height = mt->logical_height0;
   }

   BEGIN_BATCH(7);
   /* 3DSTATE_DEPTH_BUFFER dw0 */
   OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));

   /* 3DSTATE_DEPTH_BUFFER dw1 */
   OUT_BATCH((depth_mt ? depth_mt->pitch - 1 : 0) |
             (depthbuffer_format << 18) |
             ((enable_hiz_ss ? 1 : 0) << 21) | /* separate stencil enable */
             ((enable_hiz_ss ? 1 : 0) << 22) | /* hiz enable */
             (BRW_TILEWALK_YMAJOR << 26) |
             ((depth_mt ? depth_mt->tiling != I915_TILING_NONE : 1)
              << 27) |
             (surftype << 29));

   /* 3DSTATE_DEPTH_BUFFER dw2 */
   if (depth_mt) {
      OUT_RELOC(depth_mt->bo,
		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
		0);
   } else {
      OUT_BATCH(0);
   }

   /* 3DSTATE_DEPTH_BUFFER dw3 */
   OUT_BATCH(((width - 1) << 6) |
             ((height - 1) << 19) |
             lod << 2);

   /* 3DSTATE_DEPTH_BUFFER dw4 */
   OUT_BATCH((depth - 1) << 21 |
             min_array_element << 10 |
             (depth - 1) << 1);

   /* 3DSTATE_DEPTH_BUFFER dw5 */
   OUT_BATCH(0);
   assert(tile_x == 0 && tile_y == 0);

   /* 3DSTATE_DEPTH_BUFFER dw6 */
   OUT_BATCH(0);

   ADVANCE_BATCH();

   if (hiz || separate_stencil) {
      /*
       * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate
       * stencil enable' and 'hiz enable' bits were set. Therefore we must
       * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if
       * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted;
       * failure to do so causes hangs on gen5 and a stall on gen6.
       */

      /* Emit hiz buffer. */
      if (hiz) {
         struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_buf->mt;
         uint32_t offset = 0;

         if (hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
            offset = intel_miptree_get_aligned_offset(
                        hiz_mt,
                        hiz_mt->level[lod].level_x,
                        hiz_mt->level[lod].level_y,
                        false);
         }

	 BEGIN_BATCH(3);
	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
	 OUT_BATCH(hiz_mt->pitch - 1);
	 OUT_RELOC(hiz_mt->bo,
		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
		   offset);
	 ADVANCE_BATCH();
      } else {
	 BEGIN_BATCH(3);
	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
	 OUT_BATCH(0);
	 OUT_BATCH(0);
	 ADVANCE_BATCH();
      }

      /* Emit stencil buffer. */
      if (separate_stencil) {
         uint32_t offset = 0;

         if (stencil_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
            if (stencil_mt->format == MESA_FORMAT_S_UINT8) {
               /* Note: we can't compute the stencil offset using
                * intel_region_get_aligned_offset(), because stencil_region
                * claims that the region is untiled even though it's W tiled.
                */
               offset =
                  stencil_mt->level[lod].level_y * stencil_mt->pitch +
                  stencil_mt->level[lod].level_x * 64;
            } else {
               offset = intel_miptree_get_aligned_offset(
                           stencil_mt,
                           stencil_mt->level[lod].level_x,
                           stencil_mt->level[lod].level_y,
                           false);
            }
         }

	 BEGIN_BATCH(3);
	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
         /* The stencil buffer has quirky pitch requirements.  From Vol 2a,
          * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
          *    The pitch must be set to 2x the value computed based on width, as
          *    the stencil buffer is stored with two rows interleaved.
          */
	 OUT_BATCH(2 * stencil_mt->pitch - 1);
	 OUT_RELOC(stencil_mt->bo,
		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
		   offset);
	 ADVANCE_BATCH();
      } else {
	 BEGIN_BATCH(3);
	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
	 OUT_BATCH(0);
	 OUT_BATCH(0);
	 ADVANCE_BATCH();
      }
   }

   /*
    * On Gen >= 6, emit clear params for safety. If using hiz, then clear
    * params must be emitted.
    *
    * From Section 2.11.5.6.4.1 3DSTATE_CLEAR_PARAMS:
    *     3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE packet
    *     when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
    */
   BEGIN_BATCH(2);
   OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 |
             GEN5_DEPTH_CLEAR_VALID |
             (2 - 2));
   OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
   ADVANCE_BATCH();
}
コード例 #8
0
/* Awful vtable-compatible function; should be cleaned up in the future. */
void
gen8_emit_depth_stencil_hiz(struct brw_context *brw,
                            struct intel_mipmap_tree *depth_mt,
                            uint32_t depth_offset,
                            uint32_t depthbuffer_format,
                            uint32_t depth_surface_type,
                            struct intel_mipmap_tree *stencil_mt,
                            bool hiz, bool separate_stencil,
                            uint32_t width, uint32_t height,
                            uint32_t tile_x, uint32_t tile_y)
{
   struct gl_context *ctx = &brw->ctx;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   uint32_t surftype;
   unsigned int depth = 1;
   unsigned int min_array_element;
   GLenum gl_target = GL_TEXTURE_2D;
   unsigned int lod;
   const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt;
   const struct intel_renderbuffer *irb = NULL;
   const struct gl_renderbuffer *rb = NULL;

   irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
   if (!irb)
      irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
   rb = (struct gl_renderbuffer *) irb;

   if (rb) {
      depth = MAX2(rb->Depth, 1);
      if (rb->TexImage)
         gl_target = rb->TexImage->TexObject->Target;
   }

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      /* The PRM claims that we should use BRW_SURFACE_CUBE for this
       * situation, but experiments show that gl_Layer doesn't work when we do
       * this.  So we use BRW_SURFACE_2D, since for rendering purposes this is
       * equivalent.
       */
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   if (fb->MaxNumLayers > 0 || !irb) {
      min_array_element = 0;
   } else if (irb->mt->num_samples > 1) {
      /* Convert physical to logical layer. */
      min_array_element = irb->mt_layer / irb->mt->num_samples;
   } else {
      min_array_element = irb->mt_layer;
   }

   lod = irb ? irb->mt_level - irb->mt->first_level : 0;

   if (mt) {
      width = mt->logical_width0;
      height = mt->logical_height0;
   }

   emit_depth_packets(brw, depth_mt, brw_depthbuffer_format(brw), surftype,
                      ctx->Depth.Mask != 0,
                      stencil_mt, ctx->Stencil._WriteEnabled,
                      brw->depthstencil.stencil_offset,
                      hiz, width, height, depth, lod, min_array_element);
}