From: Jason Ekstrand Date: Fri, 7 Oct 2016 05:10:34 +0000 (-0700) Subject: intel/blorp: Add support for binding an actual stencil buffer X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=563fa63bf2245e84584efb1143ea5acd7374df46;p=mesa.git intel/blorp: Add support for binding an actual stencil buffer 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 Reviewed-by: Topi Pohjolainen --- diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h index ebad253515f..85fb7549f80 100644 --- a/src/intel/blorp/blorp_genX_exec.h +++ b/src/intel/blorp/blorp_genX_exec.h @@ -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(¶ms->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) { diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index c7989d9974c..2250a7a9fdf 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -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;