db.SurfaceFormat = isl_surf_get_depth_format(dev, info->depth_surf);
db.Width = info->depth_surf->logical_level0_px.width - 1;
db.Height = info->depth_surf->logical_level0_px.height - 1;
+ if (db.SurfaceType == SURFTYPE_3D)
+ db.Depth = info->depth_surf->logical_level0_px.depth - 1;
} else if (info->stencil_surf) {
db.SurfaceType = isl_to_gen_ds_surftype[info->stencil_surf->dim];
db.SurfaceFormat = D32_FLOAT;
db.Width = info->stencil_surf->logical_level0_px.width - 1;
db.Height = info->stencil_surf->logical_level0_px.height - 1;
+ if (db.SurfaceType == SURFTYPE_3D)
+ db.Depth = info->stencil_surf->logical_level0_px.depth - 1;
} else {
db.SurfaceType = SURFTYPE_NULL;
db.SurfaceFormat = D32_FLOAT;
if (info->depth_surf || info->stencil_surf) {
/* These are based entirely on the view */
- db.Depth = db.RenderTargetViewExtent = info->view->array_len - 1;
+ db.RenderTargetViewExtent = info->view->array_len - 1;
db.LOD = info->view->base_level;
db.MinimumArrayElement = info->view->base_array_layer;
+
+ /* From the Haswell PRM docs for 3DSTATE_DEPTH_BUFFER::Depth
+ *
+ * "This field specifies the total number of levels for a volume
+ * texture or the number of array elements allowed to be accessed
+ * starting at the Minimum Array Element for arrayed surfaces. If the
+ * volume texture is MIP-mapped, this field specifies the depth of
+ * the base MIP level."
+ *
+ * For 3D surfaces, we set it to the correct depth above. For non-3D
+ * surfaces, this is the same as RenderTargetViewExtent.
+ */
+ if (db.SurfaceType != SURFTYPE_3D)
+ db.Depth = db.RenderTargetViewExtent;
}
if (info->depth_surf) {
#endif
db.SurfaceBaseAddress = info->depth_address;
#if GEN_GEN >= 6
- db.DepthBufferMOCS = info->mocs;
+ db.MOCS = info->mocs;
#endif
#if GEN_GEN <= 6
db.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->depth_surf) >> 2;
#endif
+
+#if GEN_GEN >= 12
+ db.ControlSurfaceEnable = db.DepthBufferCompressionEnable =
+ isl_aux_usage_has_ccs(info->hiz_usage);
+#endif
}
#if GEN_GEN == 5 || GEN_GEN == 6
#endif
if (info->stencil_surf) {
-#if GEN_GEN >= 7
+#if GEN_GEN >= 7 && GEN_GEN < 12
db.StencilWriteEnable = true;
#endif
-#if GEN_GEN >= 8 || GEN_IS_HASWELL
+#if GEN_GEN >= 12
+ sb.StencilWriteEnable = true;
+ sb.SurfaceType = SURFTYPE_2D;
+ sb.Width = info->stencil_surf->logical_level0_px.width - 1;
+ sb.Height = info->stencil_surf->logical_level0_px.height - 1;
+ sb.Depth = sb.RenderTargetViewExtent = info->view->array_len - 1;
+ sb.SurfLOD = info->view->base_level;
+ sb.MinimumArrayElement = info->view->base_array_layer;
+ assert(info->stencil_aux_usage == ISL_AUX_USAGE_NONE ||
+ info->stencil_aux_usage == ISL_AUX_USAGE_STC_CCS);
+ sb.StencilCompressionEnable =
+ info->stencil_aux_usage == ISL_AUX_USAGE_STC_CCS;
+ sb.ControlSurfaceEnable = sb.StencilCompressionEnable;
+#elif GEN_GEN >= 8 || GEN_IS_HASWELL
sb.StencilBufferEnable = true;
#endif
sb.SurfaceBaseAddress = info->stencil_address;
#if GEN_GEN >= 6
- sb.StencilBufferMOCS = info->mocs;
+ sb.MOCS = info->mocs;
#endif
sb.SurfacePitch = info->stencil_surf->row_pitch_B - 1;
#if GEN_GEN >= 8
sb.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->stencil_surf) >> 2;
+#endif
+ } else {
+#if GEN_GEN >= 12
+ sb.SurfaceType = SURFTYPE_NULL;
+
+ /* The docs seem to indicate that if surf-type is null, then we may need
+ * to match the depth-buffer value for `Depth`. It may be a
+ * documentation bug, since the other fields don't require this.
+ *
+ * TODO: Confirm documentation and remove seeting of `Depth` if not
+ * required.
+ */
+ sb.Depth = db.Depth;
#endif
}
};
assert(info->hiz_usage == ISL_AUX_USAGE_NONE ||
- info->hiz_usage == ISL_AUX_USAGE_HIZ);
- if (info->hiz_usage == ISL_AUX_USAGE_HIZ) {
+ isl_aux_usage_has_hiz(info->hiz_usage));
+ if (isl_aux_usage_has_hiz(info->hiz_usage)) {
+ assert(GEN_GEN >= 12 || info->hiz_usage == ISL_AUX_USAGE_HIZ);
db.HierarchicalDepthBufferEnable = true;
hiz.SurfaceBaseAddress = info->hiz_address;
- hiz.HierarchicalDepthBufferMOCS = info->mocs;
+ hiz.MOCS = info->mocs;
hiz.SurfacePitch = info->hiz_surf->row_pitch_B - 1;
+#if GEN_GEN >= 12
+ hiz.HierarchicalDepthBufferWriteThruEnable =
+ info->hiz_usage == ISL_AUX_USAGE_HIZ_CCS_WT;
+
+ /* The bspec docs for this bit are fairly unclear about exactly what is
+ * and isn't supported with HiZ write-through. It's fairly clear that
+ * you can't sample from a multisampled depth buffer with CCS. This
+ * limitation isn't called out explicitly but the docs for the CCS_E
+ * value of RENDER_SURFACE_STATE::AuxiliarySurfaceMode say:
+ *
+ * "If Number of multisamples > 1, programming this value means MSAA
+ * compression is enabled for that surface. Auxillary surface is MSC
+ * with tile y."
+ *
+ * Since this interpretation ignores whether the surface is
+ * depth/stencil or not and since multisampled depth buffers use
+ * ISL_MSAA_LAYOUT_INTERLEAVED which is incompatible with MCS
+ * compression, this means that we can't even specify MSAA depth CCS in
+ * RENDER_SURFACE_STATE::AuxiliarySurfaceMode. The BSpec also says, for
+ * 3DSTATE_HIER_DEPTH_BUFFER::HierarchicalDepthBufferWriteThruEnable,
+ *
+ * "This bit must NOT be set for >1x MSAA modes, since sampler
+ * doesn't support sampling from >1x MSAA depth buffer."
+ *
+ * Again, this is all focused around what the sampler can do and not
+ * what the depth hardware can do.
+ *
+ * Reading even more internal docs which can't be quoted here makes it
+ * pretty clear that, even if it's not currently called out in the
+ * BSpec, HiZ+CCS write-through isn't intended to work with MSAA and we
+ * shouldn't try to use it. Treat it as if it's disallowed even if the
+ * BSpec doesn't explicitly document that.
+ */
+ if (hiz.HierarchicalDepthBufferWriteThruEnable)
+ assert(info->depth_surf->samples == 1);
+#endif
+
#if GEN_GEN >= 8
/* From the SKL PRM Vol2a:
*
GENX(3DSTATE_HIER_DEPTH_BUFFER_pack)(NULL, dw, &hiz);
dw += GENX(3DSTATE_HIER_DEPTH_BUFFER_length);
+#if GEN_GEN == 12
+ /* GEN:BUG:14010455700
+ *
+ * To avoid sporadic corruptions “Set 0x7010[9] when Depth Buffer Surface
+ * Format is D16_UNORM , surface type is not NULL & 1X_MSAA”.
+ */
+ bool enable_14010455700 =
+ info->depth_surf && info->depth_surf->samples == 1 &&
+ db.SurfaceType != SURFTYPE_NULL && db.SurfaceFormat == D16_UNORM;
+ struct GENX(COMMON_SLICE_CHICKEN1) chicken1 = {
+ .HIZPlaneOptimizationdisablebit = enable_14010455700,
+ .HIZPlaneOptimizationdisablebitMask = true,
+ };
+ uint32_t chicken1_dw;
+ GENX(COMMON_SLICE_CHICKEN1_pack)(NULL, &chicken1_dw, &chicken1);
+
+ struct GENX(MI_LOAD_REGISTER_IMM) lri = {
+ GENX(MI_LOAD_REGISTER_IMM_header),
+ .RegisterOffset = GENX(COMMON_SLICE_CHICKEN1_num),
+ .DataDWord = chicken1_dw,
+ };
+ GENX(MI_LOAD_REGISTER_IMM_pack)(NULL, dw, &lri);
+ dw += GENX(MI_LOAD_REGISTER_IMM_length);
+
+ /* GEN:BUG:1806527549
+ *
+ * Set HIZ_CHICKEN (7018h) bit 13 = 1 when depth buffer is D16_UNORM.
+ */
+ struct GENX(HIZ_CHICKEN) hiz_chicken = {
+ .HZDepthTestLEGEOptimizationDisable = db.SurfaceFormat == D16_UNORM,
+ .HZDepthTestLEGEOptimizationDisableMask = true,
+ };
+ uint32_t hiz_chicken_dw;
+ GENX(HIZ_CHICKEN_pack)(NULL, &hiz_chicken_dw, &hiz_chicken);
+
+ struct GENX(MI_LOAD_REGISTER_IMM) lri2 = {
+ GENX(MI_LOAD_REGISTER_IMM_header),
+ .RegisterOffset = GENX(HIZ_CHICKEN_num),
+ .DataDWord = hiz_chicken_dw,
+ };
+ GENX(MI_LOAD_REGISTER_IMM_pack)(NULL, dw, &lri2);
+ dw += GENX(MI_LOAD_REGISTER_IMM_length);
+#endif
+
GENX(3DSTATE_CLEAR_PARAMS_pack)(NULL, dw, &clear);
dw += GENX(3DSTATE_CLEAR_PARAMS_length);
#endif