intel/blorp: Add support for binding an actual stencil buffer
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 7 Oct 2016 05:10:34 +0000 (22:10 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 14 Oct 2016 22:39:41 +0000 (15:39 -0700)
While we're here, we also make depth without HiZ work.

v2:
 - Use the correct surface type for 1-D on SKL+
 - Set QPitch on BDW+

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/intel/blorp/blorp_genX_exec.h
src/intel/blorp/blorp_priv.h

index ebad253515fb407b8d0f569952c98990d4eddf50..85fb7549f80323c1eae79984db3c2462fdcc5cde 100644 (file)
@@ -719,6 +719,24 @@ blorp_emit_ps_config(struct blorp_batch *batch,
 #endif /* GEN_GEN */
 }
 
+static const uint32_t isl_to_gen_ds_surftype [] = {
+#if GEN_GEN >= 9
+   /* From the SKL PRM, "3DSTATE_DEPTH_STENCIL::SurfaceType":
+    *
+    *    "If depth/stencil is enabled with 1D render target, depth/stencil
+    *    surface type needs to be set to 2D surface type and height set to 1.
+    *    Depth will use (legacy) TileY and stencil will use TileW. For this
+    *    case only, the Surface Type of the depth buffer can be 2D while the
+    *    Surface Type of the render target(s) are 1D, representing an
+    *    exception to a programming note above.
+    */
+   [ISL_SURF_DIM_1D] = SURFTYPE_2D,
+#else
+   [ISL_SURF_DIM_1D] = SURFTYPE_1D,
+#endif
+   [ISL_SURF_DIM_2D] = SURFTYPE_2D,
+   [ISL_SURF_DIM_3D] = SURFTYPE_3D,
+};
 
 static void
 blorp_emit_depth_stencil_config(struct blorp_batch *batch,
@@ -731,54 +749,80 @@ blorp_emit_depth_stencil_config(struct blorp_batch *batch,
 #endif
 
    blorp_emit(batch, GENX(3DSTATE_DEPTH_BUFFER), db) {
-      switch (params->depth.surf.dim) {
-      case ISL_SURF_DIM_1D:
-         db.SurfaceType = SURFTYPE_1D;
-         break;
-      case ISL_SURF_DIM_2D:
-         db.SurfaceType = SURFTYPE_2D;
-         break;
-      case ISL_SURF_DIM_3D:
-         db.SurfaceType = SURFTYPE_3D;
-         break;
-      }
-
-      db.SurfaceFormat = params->depth_format;
-
 #if GEN_GEN >= 7
-      db.DepthWriteEnable = true;
+      db.DepthWriteEnable = params->depth.addr.buffer != NULL;
+      db.StencilWriteEnable = params->stencil.addr.buffer != NULL;
 #endif
 
 #if GEN_GEN <= 6
-      db.TiledSurface = true;
-      db.TileWalk = TILEWALK_YMAJOR;
-      db.MIPMapLayoutMode = MIPLAYOUT_BELOW;
       db.SeparateStencilBufferEnable = true;
 #endif
 
-      db.HierarchicalDepthBufferEnable = true;
+      if (params->depth.addr.buffer) {
+         db.SurfaceFormat = params->depth_format;
+         db.SurfaceType = isl_to_gen_ds_surftype[params->depth.surf.dim];
+
+#if GEN_GEN <= 6
+         db.TiledSurface = true;
+         db.TileWalk = TILEWALK_YMAJOR;
+         db.MIPMapLayoutMode = MIPLAYOUT_BELOW;
+#endif
+
+         db.HierarchicalDepthBufferEnable =
+            params->depth.aux_usage == ISL_AUX_USAGE_HIZ;
+
+         db.Width = params->depth.surf.logical_level0_px.width - 1;
+         db.Height = params->depth.surf.logical_level0_px.height - 1;
+         db.RenderTargetViewExtent = db.Depth =
+            params->depth.view.array_len - 1;
+
+         db.LOD = params->depth.view.base_level;
+         db.MinimumArrayElement = params->depth.view.base_array_layer;
+
+         db.SurfacePitch = params->depth.surf.row_pitch - 1;
+         db.SurfaceBaseAddress = params->depth.addr;
+         db.DepthBufferMOCS = mocs;
+      } else {
+         db.SurfaceFormat = D32_FLOAT;
+         db.SurfaceType = isl_to_gen_ds_surftype[params->stencil.surf.dim];
 
-      db.Width = params->depth.surf.logical_level0_px.width - 1;
-      db.Height = params->depth.surf.logical_level0_px.height - 1;
-      db.RenderTargetViewExtent = db.Depth =
-         MAX2(params->depth.surf.logical_level0_px.depth,
-              params->depth.surf.logical_level0_px.array_len) - 1;
+         /* If we don't have a depth buffer, pull dimensions from stencil */
+         assert(params->stencil.addr.buffer != NULL);
 
-      db.LOD = params->depth.view.base_level;
-      db.MinimumArrayElement = params->depth.view.base_array_layer;
+         db.Width = params->stencil.surf.logical_level0_px.width - 1;
+         db.Height = params->stencil.surf.logical_level0_px.height - 1;
+         db.RenderTargetViewExtent = db.Depth =
+            params->stencil.view.array_len - 1;
 
-      db.SurfacePitch = params->depth.surf.row_pitch - 1;
-      db.SurfaceBaseAddress = params->depth.addr;
-      db.DepthBufferMOCS = mocs;
+         db.LOD = params->stencil.view.base_level;
+         db.MinimumArrayElement = params->stencil.view.base_array_layer;
+      }
    }
 
    blorp_emit(batch, GENX(3DSTATE_HIER_DEPTH_BUFFER), hiz) {
-      hiz.SurfacePitch = params->depth.aux_surf.row_pitch - 1;
-      hiz.SurfaceBaseAddress = params->depth.aux_addr;
-      hiz.HierarchicalDepthBufferMOCS = mocs;
+      if (params->depth.aux_usage == ISL_AUX_USAGE_HIZ) {
+         hiz.SurfacePitch = params->depth.aux_surf.row_pitch - 1;
+         hiz.SurfaceBaseAddress = params->depth.aux_addr;
+         hiz.HierarchicalDepthBufferMOCS = mocs;
+      }
    }
 
-   blorp_emit(batch, GENX(3DSTATE_STENCIL_BUFFER), sb);
+   blorp_emit(batch, GENX(3DSTATE_STENCIL_BUFFER), sb) {
+      if (params->stencil.addr.buffer) {
+#if GEN_GEN >= 8 || GEN_IS_HASWELL
+         sb.StencilBufferEnable = true;
+#endif
+
+         sb.SurfacePitch = params->stencil.surf.row_pitch - 1,
+#if GEN_GEN >= 8
+         sb.SurfaceQPitch =
+            isl_surf_get_array_pitch_el_rows(&params->stencil.surf) >> 2,
+#endif
+
+         sb.SurfaceBaseAddress = params->stencil.addr;
+         sb.StencilBufferMOCS = batch->blorp->mocs.tex;
+      }
+   }
 
    /* 3DSTATE_CLEAR_PARAMS
     *
@@ -1208,7 +1252,7 @@ blorp_exec(struct blorp_batch *batch, const struct blorp_params *params)
 
    blorp_emit_viewport_state(batch, params);
 
-   if (params->depth.addr.buffer) {
+   if (params->depth.addr.buffer || params->stencil.addr.buffer) {
       blorp_emit_depth_stencil_config(batch, params);
    } else {
       blorp_emit(batch, GENX(3DSTATE_DEPTH_BUFFER), db) {
index c7989d9974c89ed009170ed70d20bf3d6a72e870..2250a7a9fdf2b5b9ba581470aaf947dd89001f9d 100644 (file)
@@ -182,6 +182,7 @@ struct blorp_params
    uint32_t y1;
    float z;
    struct brw_blorp_surface_info depth;
+   struct brw_blorp_surface_info stencil;
    uint32_t depth_format;
    struct brw_blorp_surface_info src;
    struct brw_blorp_surface_info dst;