From ebbb8242404eaaedccbaa0a42e686dbde59fb302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Thu, 25 Apr 2024 13:29:45 +0200 Subject: [PATCH] v3dv: fixes StencilTestEnable handling While working on VK_EXT_extended_dynamic_state2 we found two issues the stencil emission code, after the update for StencilTestEnable being dynamic. Specifically: * pack_stencil_cfg: if we don't have a ds_info, we need to return, as pack_single_stencil_cfg uses it to fill it up. Also the check for MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE was not needed. That state doesn't affect the content of the STENCIL_CFG packet. Stencil is enabled/disabled at the CFG_BITS packet. * cmd_buffer_emit_stencil: we can't use pipeline->emit_stencil_cfg to filter if it is needed to emit that as since stencil_test_enable and stencil_op become dynamic. We also update which states we check that are dynamic. As mentioned STENCIL_TEST_ENABLE doesn't affect here. Fixes: 60e9237e81c ("v3dv: StencilOp and StencilTestEnable are now dynamic") Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dvx_cmd_buffer.c | 59 ++++++++++++++------------ src/broadcom/vulkan/v3dvx_pipeline.c | 4 +- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 31cd9097f3b..9fd62a34c98 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -1434,6 +1434,11 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer) struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state; + bool has_stencil = + pipeline->rendering_info.stencil_attachment_format != VK_FORMAT_UNDEFINED; + + if (!(dyn->ds.stencil.test_enable && has_stencil)) + return; v3dv_cl_ensure_space_with_branch(&job->bcl, 2 * cl_packet_length(STENCIL_CFG)); @@ -1452,36 +1457,36 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer) const bool needs_front_and_back = any_dynamic_stencil_state ? memcmp(front, back, sizeof(*front)) != 0 : pipeline->emit_stencil_cfg[1] == true; - const unsigned stencil_packets = needs_front_and_back ? 2 : 1; - for (uint32_t i = 0; i < stencil_packets; i++) { - if (pipeline->emit_stencil_cfg[i]) { - if (any_dynamic_stencil_state) { - const struct vk_stencil_test_face_state *stencil_state = - i == 0 ? front : back; - - /* If we have any dynamic stencil state we just emit the entire - * packet since for simplicity - */ - cl_emit(&job->bcl, STENCIL_CFG, config) { - config.front_config = !needs_front_and_back || i == 0; - config.back_config = !needs_front_and_back || i == 1; - config.stencil_test_mask = stencil_state->compare_mask & 0xff; - config.stencil_write_mask = stencil_state->write_mask & 0xff; - config.stencil_ref_value = stencil_state->reference & 0xff; - config.stencil_test_function = stencil_state->op.compare; - config.stencil_pass_op = - v3dX(translate_stencil_op)(stencil_state->op.pass); - config.depth_test_fail_op = - v3dX(translate_stencil_op)(stencil_state->op.depth_fail); - config.stencil_test_fail_op = - v3dX(translate_stencil_op)(stencil_state->op.fail); - } - } else { - cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]); + for (uint32_t i = 0; i < 2; i++) { + if (any_dynamic_stencil_state) { + const struct vk_stencil_test_face_state *stencil_state = + i == 0 ? front : back; + /* If we have any dynamic stencil state we just emit the entire + * packet since for simplicity + */ + cl_emit(&job->bcl, STENCIL_CFG, config) { + config.front_config = !needs_front_and_back || i == 0; + config.back_config = !needs_front_and_back || i == 1; + config.stencil_test_mask = stencil_state->compare_mask & 0xff; + config.stencil_write_mask = stencil_state->write_mask & 0xff; + config.stencil_ref_value = stencil_state->reference & 0xff; + config.stencil_test_function = stencil_state->op.compare; + config.stencil_pass_op = + v3dX(translate_stencil_op)(stencil_state->op.pass); + config.depth_test_fail_op = + v3dX(translate_stencil_op)(stencil_state->op.depth_fail); + config.stencil_test_fail_op = + v3dX(translate_stencil_op)(stencil_state->op.fail); } - emitted_stencil = true; + } else { + assert(pipeline->emit_stencil_cfg[i]); + cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]); } + emitted_stencil = true; + + if (!needs_front_and_back) + break; } if (emitted_stencil) { BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK); diff --git a/src/broadcom/vulkan/v3dvx_pipeline.c b/src/broadcom/vulkan/v3dvx_pipeline.c index 125adfa7a4b..304bb0548bc 100644 --- a/src/broadcom/vulkan/v3dvx_pipeline.c +++ b/src/broadcom/vulkan/v3dvx_pipeline.c @@ -300,10 +300,8 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline, { assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG)); - if ((!ds_info || !ds_info->stencilTestEnable) && - (!BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE))) { + if (!ds_info || !ds_info->stencilTestEnable) return; - } const struct vk_render_pass_state *ri = &pipeline->rendering_info; if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)