[Mesa-dev] [PATCH 1/5] anv: Disable stencil writes when both write masks are zero
Jason Ekstrand
jason at jlekstrand.net
Thu Feb 2 04:07:22 UTC 2017
The only mechanism Vulkan provides for disabling stencil writes is to set
the stencil write mask to 0. Since that is dynamic state, we have to move
handle it late during command buffer builder. This helps Dota2 by a couple
percent because it allows the hardware to move the depth and stencil writes
to early in more cases.
v2 (Jason Ekstrand): Always initialize the new pipeline variable
---
src/intel/vulkan/anv_private.h | 1 +
src/intel/vulkan/gen7_cmd_buffer.c | 4 ++++
src/intel/vulkan/gen8_cmd_buffer.c | 8 ++++++++
src/intel/vulkan/genX_pipeline.c | 4 +++-
4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index a0cb35c..4fe3ebc 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1465,6 +1465,7 @@ struct anv_pipeline {
uint32_t cs_right_mask;
+ bool writes_stencil;
bool depth_clamp_enable;
struct {
diff --git a/src/intel/vulkan/gen7_cmd_buffer.c b/src/intel/vulkan/gen7_cmd_buffer.c
index 8d68aba..013ed87 100644
--- a/src/intel/vulkan/gen7_cmd_buffer.c
+++ b/src/intel/vulkan/gen7_cmd_buffer.c
@@ -212,6 +212,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
.BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
+
+ .StencilBufferWriteEnable =
+ (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+ pipeline->writes_stencil,
};
GENX(DEPTH_STENCIL_STATE_pack)(NULL, depth_stencil_dw, &depth_stencil);
diff --git a/src/intel/vulkan/gen8_cmd_buffer.c b/src/intel/vulkan/gen8_cmd_buffer.c
index ab68872..8c8de62 100644
--- a/src/intel/vulkan/gen8_cmd_buffer.c
+++ b/src/intel/vulkan/gen8_cmd_buffer.c
@@ -224,6 +224,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
.BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
+
+ .StencilBufferWriteEnable =
+ (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+ pipeline->writes_stencil,
};
GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, wm_depth_stencil_dw,
&wm_depth_stencil);
@@ -271,6 +275,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.StencilReferenceValue = d->stencil_reference.front & 0xff,
.BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff,
+
+ .StencilBufferWriteEnable =
+ (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+ pipeline->writes_stencil,
};
GEN9_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, dwords, &wm_depth_stencil);
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 9d28466..18fe48c 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -652,12 +652,15 @@ emit_ds_state(struct anv_pipeline *pipeline,
/* We're going to OR this together with the dynamic state. We need
* to make sure it's initialized to something useful.
*/
+ pipeline->writes_stencil = false;
memset(depth_stencil_dw, 0, sizeof(depth_stencil_dw));
return;
}
/* VkBool32 depthBoundsTestEnable; // optional (depth_bounds_test) */
+ pipeline->writes_stencil = info->stencilTestEnable;
+
#if GEN_GEN <= 7
struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
#else
@@ -669,7 +672,6 @@ emit_ds_state(struct anv_pipeline *pipeline,
.DoubleSidedStencilEnable = true,
.StencilTestEnable = info->stencilTestEnable,
- .StencilBufferWriteEnable = info->stencilTestEnable,
.StencilFailOp = vk_to_gen_stencil_op[info->front.failOp],
.StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.passOp],
.StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.depthFailOp],
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list