From 396da5c029549a78e0536f2a7910ee791bb6223b Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 22 May 2019 11:23:03 +0200 Subject: [PATCH] radv: clear the depth/stencil resolve attachment if necessary The driver might need to clear one aspect of the depth/stencil resolve attachment before performing the resolve itself. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_meta_clear.c | 73 ++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 6263b6d6f58..c3def76e957 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -715,13 +715,14 @@ static void emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_att, const VkClearRect *clear_rect, + struct radv_subpass_attachment *ds_att, uint32_t view_mask) { struct radv_device *device = cmd_buffer->device; struct radv_meta_state *meta_state = &device->meta_state; const struct radv_subpass *subpass = cmd_buffer->state.subpass; const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; - const uint32_t pass_att = subpass->depth_stencil_attachment->attachment; + const uint32_t pass_att = ds_att->attachment; VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; VkImageAspectFlags aspects = clear_att->aspectMask; const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL; @@ -761,18 +762,25 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, iview, samples_log2, aspects, - subpass->depth_stencil_attachment->layout, + ds_att->layout, clear_rect, clear_value); if (!pipeline) return; + struct radv_subpass clear_subpass = { + .color_count = 0, + .color_attachments = NULL, + .depth_stencil_attachment = ds_att, + }; + + radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass); + radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, - subpass->depth_stencil_attachment->layout, - clear_rect, clear_value)) + ds_att->layout, clear_rect, clear_value)) radv_update_ds_clear_metadata(cmd_buffer, iview->image, clear_value, aspects); @@ -799,6 +807,8 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, prev_reference); } + + radv_cmd_buffer_set_subpass(cmd_buffer, subpass); } static uint32_t @@ -1620,7 +1630,8 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearRect *clear_rect, enum radv_cmd_flush_bits *pre_flush, enum radv_cmd_flush_bits *post_flush, - uint32_t view_mask) + uint32_t view_mask, + bool ds_resolve_clear) { const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; const struct radv_subpass *subpass = cmd_buffer->state.subpass; @@ -1646,12 +1657,16 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask); } } else { - const uint32_t pass_att = subpass->depth_stencil_attachment->attachment; - if (pass_att == VK_ATTACHMENT_UNUSED) + struct radv_subpass_attachment *ds_att = subpass->depth_stencil_attachment; + + if (ds_resolve_clear) + ds_att = subpass->ds_resolve_attachment; + + if (ds_att->attachment == VK_ATTACHMENT_UNUSED) return; - VkImageLayout image_layout = subpass->depth_stencil_attachment->layout; - const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL; + VkImageLayout image_layout = ds_att->layout; + const struct radv_image_view *iview = fb ? fb->attachments[ds_att->attachment].attachment : NULL; VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | @@ -1664,7 +1679,7 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, pre_flush, post_flush); } else { emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect, - view_mask); + ds_att, view_mask); } } } @@ -1693,10 +1708,16 @@ radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) return true; } - if (!cmd_state->subpass->depth_stencil_attachment) + if (cmd_state->subpass->depth_stencil_attachment) { + a = cmd_state->subpass->depth_stencil_attachment->attachment; + if (radv_attachment_needs_clear(cmd_state, a)) + return true; + } + + if (!cmd_state->subpass->ds_resolve_attachment) return false; - a = cmd_state->subpass->depth_stencil_attachment->attachment; + a = cmd_state->subpass->ds_resolve_attachment->attachment; return radv_attachment_needs_clear(cmd_state, a); } @@ -1705,7 +1726,8 @@ radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, struct radv_attachment_state *attachment, const VkClearAttachment *clear_att, enum radv_cmd_flush_bits *pre_flush, - enum radv_cmd_flush_bits *post_flush) + enum radv_cmd_flush_bits *post_flush, + bool ds_resolve_clear) { struct radv_cmd_state *cmd_state = &cmd_buffer->state; uint32_t view_mask = cmd_state->subpass->view_mask; @@ -1717,7 +1739,7 @@ radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, }; emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush, - view_mask & ~attachment->cleared_views); + view_mask & ~attachment->cleared_views, ds_resolve_clear); if (view_mask) attachment->cleared_views |= view_mask; else @@ -1762,7 +1784,7 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) radv_subpass_clear_attachment(cmd_buffer, &cmd_state->attachments[a], &clear_att, &pre_flush, - &post_flush); + &post_flush, false); } if (cmd_state->subpass->depth_stencil_attachment) { @@ -1776,7 +1798,22 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) radv_subpass_clear_attachment(cmd_buffer, &cmd_state->attachments[ds], &clear_att, &pre_flush, - &post_flush); + &post_flush, false); + } + } + + if (cmd_state->subpass->ds_resolve_attachment) { + uint32_t ds_resolve = cmd_state->subpass->ds_resolve_attachment->attachment; + if (radv_attachment_needs_clear(cmd_state, ds_resolve)) { + VkClearAttachment clear_att = { + .aspectMask = cmd_state->attachments[ds_resolve].pending_clear_aspects, + .clearValue = cmd_state->attachments[ds_resolve].clear_value, + }; + + radv_subpass_clear_attachment(cmd_buffer, + &cmd_state->attachments[ds_resolve], + &clear_att, &pre_flush, + &post_flush, true); } } @@ -1904,7 +1941,7 @@ radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer, .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */ }; - emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0); + emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0, false); radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); radv_DestroyRenderPass(device_h, pass, @@ -2129,7 +2166,7 @@ void radv_CmdClearAttachments( for (uint32_t a = 0; a < attachmentCount; ++a) { for (uint32_t r = 0; r < rectCount; ++r) { emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush, - cmd_buffer->state.subpass->view_mask); + cmd_buffer->state.subpass->view_mask, false); } } -- 2.30.2