From bed4ad26ad050ac6ea38167411277b4f110eb48f Mon Sep 17 00:00:00 2001 From: Amber Date: Wed, 3 Apr 2024 20:11:11 +0200 Subject: [PATCH] tu: Disable depth and stencil tests when attachment state requires it The depth and stencil tests should be disabled in case the respective attachments are null in VkRenderingInfo or their format is undefined in VkPipelineRenderingCreateInfo, additionally the stencil test should be disabled in case the depth/stencil attachment has no stencil component. Fixes: dEQP-VK.pipeline.*.stencil.no_stencil_att.*.d24_unorm_s8_uint dEQP-VK.pipeline.*.stencil.no_stencil_att.*.x8_d24_unorm_pack32 Signed-off-by: Amber Harmonia Part-of: --- src/freedreno/vulkan/tu_pass.cc | 14 ++++++++++++- src/freedreno/vulkan/tu_pass.h | 10 +++++++++ src/freedreno/vulkan/tu_pipeline.cc | 32 ++++++++++++++++++----------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/freedreno/vulkan/tu_pass.cc b/src/freedreno/vulkan/tu_pass.cc index 032b4c729e9..cb18611d88e 100644 --- a/src/freedreno/vulkan/tu_pass.cc +++ b/src/freedreno/vulkan/tu_pass.cc @@ -976,8 +976,11 @@ tu_CreateRenderPass2(VkDevice _device, uint32_t a = desc->pDepthStencilAttachment ? desc->pDepthStencilAttachment->attachment : VK_ATTACHMENT_UNUSED; subpass->depth_stencil_attachment.attachment = a; - if (a != VK_ATTACHMENT_UNUSED) + subpass->depth_used = a != VK_ATTACHMENT_UNUSED; + subpass->stencil_used = a != VK_ATTACHMENT_UNUSED; + if (a != VK_ATTACHMENT_UNUSED) { tu_subpass_use_attachment(pass, i, a, pCreateInfo); + } } tu_render_pass_patch_input_gmem(pass); @@ -1125,6 +1128,9 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, att->clear_views = info->viewMask; subpass->depth_stencil_attachment.attachment = a++; + subpass->depth_used = (bool) info->pDepthAttachment; + subpass->stencil_used = (bool) info->pStencilAttachment; + attachment_set_ops( device, att, info->pDepthAttachment ? info->pDepthAttachment->loadOp @@ -1251,9 +1257,15 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer, info->depthAttachmentFormat : info->stencilAttachmentFormat; att->samples = info->rasterizationSamples; subpass->depth_stencil_attachment.attachment = a++; + subpass->depth_used = + info->depthAttachmentFormat != VK_FORMAT_UNDEFINED; + subpass->stencil_used = + info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED; att->cond_load_allowed = att->cond_store_allowed = true; } else { subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; + subpass->depth_used = false; + subpass->stencil_used = false; } tu_render_pass_calc_views(pass); diff --git a/src/freedreno/vulkan/tu_pass.h b/src/freedreno/vulkan/tu_pass.h index 7aa2f8efc1d..31005f93502 100644 --- a/src/freedreno/vulkan/tu_pass.h +++ b/src/freedreno/vulkan/tu_pass.h @@ -61,6 +61,16 @@ struct tu_subpass struct tu_subpass_attachment *color_attachments; struct tu_subpass_attachment *resolve_attachments; struct tu_subpass_attachment depth_stencil_attachment; + /* When using dynamic rendering depth and stencil attachments may be + * set to unused independently, so we need to track this bit of + * information separately for each of them. + * + * Due to VUID-vkCmdDraw-dynamicRenderingUnusedAttachments-08916 and + * VUID-vkCmdDraw-dynamicRenderingUnusedAttachments-08917 we can set + * these values at cmdBeginRendering() time. + */ + bool depth_used; + bool stencil_used; VkSampleCountFlagBits samples; diff --git a/src/freedreno/vulkan/tu_pipeline.cc b/src/freedreno/vulkan/tu_pipeline.cc index a2c543ab411..f141e25d3e7 100644 --- a/src/freedreno/vulkan/tu_pipeline.cc +++ b/src/freedreno/vulkan/tu_pipeline.cc @@ -3091,7 +3091,8 @@ static const enum mesa_vk_dynamic_graphics_state tu_ds_state[] = { template static unsigned tu6_ds_size(struct tu_device *dev, - const struct vk_depth_stencil_state *ds) + const struct vk_depth_stencil_state *ds, + const struct vk_render_pass_state *rp) { return 13; } @@ -3099,12 +3100,15 @@ tu6_ds_size(struct tu_device *dev, template static void tu6_emit_ds(struct tu_cs *cs, - const struct vk_depth_stencil_state *ds) + const struct vk_depth_stencil_state *ds, + const struct vk_render_pass_state *rp) { + bool stencil_test_enable = + ds->stencil.test_enable && rp->attachments & MESA_VK_RP_ATTACHMENT_STENCIL_BIT; tu_cs_emit_regs(cs, A6XX_RB_STENCIL_CONTROL( - .stencil_enable = ds->stencil.test_enable, - .stencil_enable_bf = ds->stencil.test_enable, - .stencil_read = ds->stencil.test_enable, + .stencil_enable = stencil_test_enable, + .stencil_enable_bf = stencil_test_enable, + .stencil_read = stencil_test_enable, .func = tu6_compare_func((VkCompareOp)ds->stencil.front.op.compare), .fail = tu6_stencil_op((VkStencilOp)ds->stencil.front.op.fail), .zpass = tu6_stencil_op((VkStencilOp)ds->stencil.front.op.pass), @@ -3113,7 +3117,7 @@ tu6_emit_ds(struct tu_cs *cs, .fail_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.fail), .zpass_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.pass), .zfail_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.depth_fail))); - tu_cs_emit_regs(cs, A6XX_GRAS_SU_STENCIL_CNTL(ds->stencil.test_enable)); + tu_cs_emit_regs(cs, A6XX_GRAS_SU_STENCIL_CNTL(stencil_test_enable)); tu_cs_emit_regs(cs, A6XX_RB_STENCILMASK( .mask = ds->stencil.front.compare_mask, @@ -3333,8 +3337,10 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder, builder->graphics_state.vp, builder->graphics_state.rp->view_mask != 0, pipeline->program.per_view_viewport); - DRAW_STATE(ds, TU_DYNAMIC_STATE_DS, - builder->graphics_state.ds); + DRAW_STATE_COND(ds, TU_DYNAMIC_STATE_DS, + attachments_valid, + builder->graphics_state.ds, + builder->graphics_state.rp); DRAW_STATE_COND(rb_depth_cntl, TU_DYNAMIC_STATE_RB_DEPTH_CNTL, attachments_valid, builder->graphics_state.ds, @@ -3519,8 +3525,10 @@ tu_emit_draw_state(struct tu_cmd_buffer *cmd) &cmd->vk.dynamic_graphics_state.vp, cmd->state.vk_rp.view_mask != 0, cmd->state.per_view_viewport); - DRAW_STATE(ds, TU_DYNAMIC_STATE_DS, - &cmd->vk.dynamic_graphics_state.ds); + DRAW_STATE_COND(ds, TU_DYNAMIC_STATE_DS, + cmd->state.dirty & TU_CMD_DIRTY_SUBPASS, + &cmd->vk.dynamic_graphics_state.ds, + &cmd->state.vk_rp); DRAW_STATE_COND(rb_depth_cntl, TU_DYNAMIC_STATE_RB_DEPTH_CNTL, cmd->state.dirty & TU_CMD_DIRTY_SUBPASS, &cmd->vk.dynamic_graphics_state.ds, @@ -3865,11 +3873,11 @@ tu_fill_render_pass_state(struct vk_render_pass_state *rp, rp->attachments = MESA_VK_RP_ATTACHMENT_NONE; if (a != VK_ATTACHMENT_UNUSED) { VkFormat ds_format = pass->attachments[a].format; - if (vk_format_has_depth(ds_format)) { + if (vk_format_has_depth(ds_format) && subpass->depth_used) { rp->depth_attachment_format = ds_format; rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; } - if (vk_format_has_stencil(ds_format)) { + if (vk_format_has_stencil(ds_format) && subpass->stencil_used) { rp->stencil_attachment_format = ds_format; rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; }