i965: Use blorp for depth/stencil clears on gen6+
authorJason Ekstrand <jason.ekstrand@intel.com>
Sun, 9 Oct 2016 05:54:00 +0000 (22:54 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jun 2017 01:15:05 +0000 (18:15 -0700)
Acked-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_blorp.c
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/brw_clear.c

index a7b24147746a8e0994849a74eb9ba2d2901dc8ca..e8993a816d56b71e968a64a6816e2e0eac476833 100644 (file)
@@ -909,6 +909,111 @@ brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb,
    return true;
 }
 
+void
+brw_blorp_clear_depth_stencil(struct brw_context *brw,
+                              struct gl_framebuffer *fb,
+                              GLbitfield mask, bool partial_clear)
+{
+   const struct gl_context *ctx = &brw->ctx;
+   struct gl_renderbuffer *depth_rb =
+      fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+   struct gl_renderbuffer *stencil_rb =
+      fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+
+   if (!depth_rb || ctx->Depth.Mask == GL_FALSE)
+      mask &= ~BUFFER_BIT_DEPTH;
+
+   if (!stencil_rb || (ctx->Stencil.WriteMask[0] & 0xff) == 0)
+      mask &= ~BUFFER_BIT_STENCIL;
+
+   if (!(mask & (BUFFER_BITS_DEPTH_STENCIL)))
+      return;
+
+   uint32_t x0, x1, y0, y1, rb_name, rb_height;
+   if (depth_rb) {
+      rb_name = depth_rb->Name;
+      rb_height = depth_rb->Height;
+      if (stencil_rb) {
+         assert(depth_rb->Width == stencil_rb->Width);
+         assert(depth_rb->Height == stencil_rb->Height);
+      }
+   } else {
+      assert(stencil_rb);
+      rb_name = stencil_rb->Name;
+      rb_height = stencil_rb->Height;
+   }
+
+   x0 = fb->_Xmin;
+   x1 = fb->_Xmax;
+   if (rb_name != 0) {
+      y0 = fb->_Ymin;
+      y1 = fb->_Ymax;
+   } else {
+      y0 = rb_height - fb->_Ymax;
+      y1 = rb_height - fb->_Ymin;
+   }
+
+   /* If the clear region is empty, just return. */
+   if (x0 == x1 || y0 == y1)
+      return;
+
+   uint32_t level, start_layer, num_layers;
+   struct isl_surf isl_tmp[4];
+   struct blorp_surf depth_surf, stencil_surf;
+
+   if (mask & BUFFER_BIT_DEPTH) {
+      struct intel_renderbuffer *irb = intel_renderbuffer(depth_rb);
+      struct intel_mipmap_tree *depth_mt =
+         find_miptree(GL_DEPTH_BUFFER_BIT, irb);
+
+      level = irb->mt_level;
+      start_layer = irb_logical_mt_layer(irb);
+      num_layers = fb->MaxNumLayers ? irb->layer_count : 1;
+
+      unsigned depth_level = level;
+      blorp_surf_for_miptree(brw, &depth_surf, depth_mt, true,
+                             true, (1 << ISL_AUX_USAGE_HIZ),
+                             &depth_level, start_layer, num_layers,
+                             &isl_tmp[0]);
+      assert(depth_level == level);
+   }
+
+   uint8_t stencil_mask = 0;
+   if (mask & BUFFER_BIT_STENCIL) {
+      struct intel_renderbuffer *irb = intel_renderbuffer(stencil_rb);
+      struct intel_mipmap_tree *stencil_mt =
+         find_miptree(GL_STENCIL_BUFFER_BIT, irb);
+
+      if (mask & BUFFER_BIT_DEPTH) {
+         assert(level == irb->mt_level);
+         assert(start_layer == irb_logical_mt_layer(irb));
+         assert(num_layers == fb->MaxNumLayers ? irb->layer_count : 1);
+      } else {
+         level = irb->mt_level;
+         start_layer = irb_logical_mt_layer(irb);
+         num_layers = fb->MaxNumLayers ? irb->layer_count : 1;
+      }
+
+      stencil_mask = ctx->Stencil.WriteMask[0] & 0xff;
+
+      unsigned stencil_level = level;
+      blorp_surf_for_miptree(brw, &stencil_surf, stencil_mt, true, true, 0,
+                             &stencil_level, start_layer, num_layers,
+                             &isl_tmp[2]);
+   }
+
+   assert((mask & BUFFER_BIT_DEPTH) || stencil_mask);
+
+   struct blorp_batch batch;
+   blorp_batch_init(&brw->blorp, &batch, brw, 0);
+   blorp_clear_depth_stencil(&batch, &depth_surf, &stencil_surf,
+                             level, start_layer, num_layers,
+                             x0, y0, x1, y1,
+                             (mask & BUFFER_BIT_DEPTH), ctx->Depth.Clear,
+                             stencil_mask, ctx->Stencil.Clear);
+   blorp_batch_finish(&batch);
+}
+
 void
 brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
                         unsigned level, unsigned layer,
index fd1b5cc944d48fd0f2e3105fe9a5986d3d259452..c8d4aeb24d70c90a35247b7d2e7e80b42e062ab8 100644 (file)
@@ -62,6 +62,10 @@ brw_blorp_copy_miptrees(struct brw_context *brw,
 bool
 brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb,
                       GLbitfield mask, bool partial_clear, bool encode_srgb);
+void
+brw_blorp_clear_depth_stencil(struct brw_context *brw,
+                              struct gl_framebuffer *fb,
+                              GLbitfield mask, bool partial_clear);
 
 void
 brw_blorp_resolve_color(struct brw_context *brw,
index 809e2790eb7c194a0ac3db0e1c6ed77b04f1952a..138997dc51aabb6200f52a971d56a4c26c7fa6c9 100644 (file)
@@ -235,6 +235,12 @@ brw_clear(struct gl_context *ctx, GLbitfield mask)
       }
    }
 
+   if (brw->gen >= 6 && (mask & BUFFER_BITS_DEPTH_STENCIL)) {
+      brw_blorp_clear_depth_stencil(brw, fb, mask, partial_clear);
+      debug_mask("blorp depth/stencil", mask & BUFFER_BITS_DEPTH_STENCIL);
+      mask &= ~BUFFER_BITS_DEPTH_STENCIL;
+   }
+
    GLbitfield tri_mask = mask & (BUFFER_BITS_COLOR |
                                 BUFFER_BIT_STENCIL |
                                 BUFFER_BIT_DEPTH);