Mesa (main): vulkan/graphics_state: Improve the depth/stencil optimization code
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jul 19 23:53:37 UTC 2022
Module: Mesa
Branch: main
Commit: 07f5f159634eee84d7ff1078d65712ddf66c3c6d
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=07f5f159634eee84d7ff1078d65712ddf66c3c6d
Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date: Thu Jul 14 20:59:38 2022 -0500
vulkan/graphics_state: Improve the depth/stencil optimization code
We now disable stencil writes when the stencil test is disabled or when
both stencil write masks are zero.
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17564>
---
src/intel/vulkan/genX_pipeline.c | 2 +-
src/vulkan/runtime/vk_graphics_state.c | 47 ++++++++++++++++++++++++++--------
src/vulkan/runtime/vk_graphics_state.h | 12 ++++++---
3 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 2508de9d66c..5fb805441a9 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -999,7 +999,7 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline,
}
struct vk_depth_stencil_state ds = *ds_in;
- vk_optimize_depth_stencil_state(&ds, ds_aspects);
+ vk_optimize_depth_stencil_state(&ds, ds_aspects, false);
pipeline->writes_stencil = ds.stencil.write_enable;
pipeline->stencil_test_enable = ds.stencil.test_enable;
pipeline->writes_depth = ds.depth.write_enable;
diff --git a/src/vulkan/runtime/vk_graphics_state.c b/src/vulkan/runtime/vk_graphics_state.c
index 19a158306fa..d01050cb009 100644
--- a/src/vulkan/runtime/vk_graphics_state.c
+++ b/src/vulkan/runtime/vk_graphics_state.c
@@ -669,7 +669,8 @@ vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state *dst,
static bool
optimize_stencil_face(struct vk_stencil_test_face_state *face,
- VkCompareOp depthCompareOp)
+ VkCompareOp depthCompareOp,
+ bool consider_write_mask)
{
/* If compareOp is ALWAYS then the stencil test will never fail and failOp
* will never happen. Set failOp to KEEP in this case.
@@ -692,6 +693,15 @@ optimize_stencil_face(struct vk_stencil_test_face_state *face,
depthCompareOp == VK_COMPARE_OP_ALWAYS)
face->op.depth_fail = VK_STENCIL_OP_KEEP;
+ /* If the write mask is zero, nothing will be written to the stencil buffer
+ * so it's as if all operations are KEEP.
+ */
+ if (consider_write_mask && face->write_mask == 0) {
+ face->op.pass = VK_STENCIL_OP_KEEP;
+ face->op.fail = VK_STENCIL_OP_KEEP;
+ face->op.depth_fail = VK_STENCIL_OP_KEEP;
+ }
+
return face->op.fail != VK_STENCIL_OP_KEEP ||
face->op.depth_fail != VK_STENCIL_OP_KEEP ||
face->op.pass != VK_STENCIL_OP_KEEP;
@@ -699,24 +709,39 @@ optimize_stencil_face(struct vk_stencil_test_face_state *face,
void
vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
- VkImageAspectFlags ds_aspects)
+ VkImageAspectFlags ds_aspects,
+ bool consider_write_mask)
{
/* stencil.write_enable is a dummy right now that should always be true */
assert(ds->stencil.write_enable);
+ /* From the Vulkan 1.3.221 spec:
+ *
+ * "If there is no depth attachment then the depth test is skipped."
+ */
+ if (!(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
+ ds->depth.test_enable = false;
+
+ /* From the Vulkan 1.3.221 spec:
+ *
+ * "...or if there is no stencil attachment, the coverage mask is
+ * unmodified by this operation."
+ */
+ if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT))
+ ds->stencil.test_enable = false;
+
/* If the depth test is disabled, we won't be writing anything. Make sure we
* treat the test as always passing later on as well.
- *
- * Also, the Vulkan spec requires that if either depth or stencil is not
- * present, the pipeline is to act as if the test silently passes. In that
- * case we won't write either.
*/
- if (!ds->depth.test_enable || !(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
+ if (!ds->depth.test_enable) {
ds->depth.write_enable = false;
ds->depth.compare_op = VK_COMPARE_OP_ALWAYS;
}
- if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ /* If the stencil test is disabled, we won't be writing anything. Make sure
+ * we treat the test as always passing later on as well.
+ */
+ if (!ds->stencil.test_enable) {
ds->stencil.write_enable = false;
ds->stencil.front.op.compare = VK_COMPARE_OP_ALWAYS;
ds->stencil.back.op.compare = VK_COMPARE_OP_ALWAYS;
@@ -742,8 +767,10 @@ vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
/* If the stencil ops are such that we don't actually ever modify the
* stencil buffer, we should disable writes.
*/
- if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op) &&
- !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op))
+ if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op,
+ consider_write_mask) &&
+ !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op,
+ consider_write_mask))
ds->stencil.write_enable = false;
/* If the depth test always passes and we never write out depth, that's the
diff --git a/src/vulkan/runtime/vk_graphics_state.h b/src/vulkan/runtime/vk_graphics_state.h
index 3f204ae6332..415ff8d62cf 100644
--- a/src/vulkan/runtime/vk_graphics_state.h
+++ b/src/vulkan/runtime/vk_graphics_state.h
@@ -410,12 +410,16 @@ struct vk_depth_stencil_state {
* hit. This function attempts to optimize the depth stencil state and
* disable writes and sometimes even testing whenever possible.
*
- * @param[inout] ds The depth stencil state to optimize
- * @param[in] ds_aspects Which image aspects are present in the render
- * pass.
+ * @param[inout] ds The depth stencil state to optimize
+ * @param[in] ds_aspects Which image aspects are present in the
+ * render pass.
+ * @param[in] consider_write_mask If true, the write mask will be taken
+ * into account when optimizing. If
+ * false, it will be ignored.
*/
void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
- VkImageAspectFlags ds_aspects);
+ VkImageAspectFlags ds_aspects,
+ bool consider_write_mask);
struct vk_color_blend_attachment_state {
/** VkPipelineColorBlendAttachmentState::blendEnable */
More information about the mesa-commit
mailing list