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; }