From a20c2e38d840c0e46a0eec590dd7b17b3e511664 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 29 Jan 2019 22:18:51 +0100 Subject: [PATCH] radv: store the list of attachments for every subpass This reworks how the depth stencil attachment is used for simplicity. This also introduces radv_render_pass_compile() helper that will be used for further optimizations. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_cmd_buffer.c | 16 +++--- src/amd/vulkan/radv_meta_clear.c | 41 +++++++++------- src/amd/vulkan/radv_meta_resolve.c | 2 +- src/amd/vulkan/radv_meta_resolve_fs.c | 2 +- src/amd/vulkan/radv_pass.c | 70 ++++++++++++++++++++------- src/amd/vulkan/radv_pipeline.c | 15 +++--- src/amd/vulkan/radv_private.h | 5 +- 7 files changed, 96 insertions(+), 55 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 003dcbd5fb2..440f09a363c 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1205,10 +1205,10 @@ radv_update_bound_fast_clear_ds(struct radv_cmd_buffer *cmd_buffer, if (!framebuffer || !subpass) return; - att_idx = subpass->depth_stencil_attachment.attachment; - if (att_idx == VK_ATTACHMENT_UNUSED) + if (!subpass->depth_stencil_attachment) return; + att_idx = subpass->depth_stencil_attachment->attachment; att = &framebuffer->attachments[att_idx]; if (att->attachment->image != image) return; @@ -1222,7 +1222,7 @@ radv_update_bound_fast_clear_ds(struct radv_cmd_buffer *cmd_buffer, */ if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && ds_clear_value.depth == 0.0) { - VkImageLayout layout = subpass->depth_stencil_attachment.layout; + VkImageLayout layout = subpass->depth_stencil_attachment->layout; radv_update_zrange_precision(cmd_buffer, &att->ds, image, layout, false); @@ -1575,9 +1575,9 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer) num_bpp64_colorbufs++; } - if(subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { - int idx = subpass->depth_stencil_attachment.attachment; - VkImageLayout layout = subpass->depth_stencil_attachment.layout; + if (subpass->depth_stencil_attachment) { + int idx = subpass->depth_stencil_attachment->attachment; + VkImageLayout layout = subpass->depth_stencil_attachment->layout; struct radv_attachment_info *att = &framebuffer->attachments[idx]; struct radv_image *image = att->attachment->image; radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo); @@ -3412,9 +3412,9 @@ radv_cmd_buffer_begin_subpass(struct radv_cmd_buffer *cmd_buffer, subpass->input_attachments[i]); } - if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { + if (subpass->depth_stencil_attachment) { radv_handle_subpass_image_transition(cmd_buffer, - subpass->depth_stencil_attachment); + *subpass->depth_stencil_attachment); } radv_cmd_buffer_set_subpass(cmd_buffer, subpass); diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 06f25aa46d7..c68ce1ee8a8 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -423,7 +423,7 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer, .color_attachments = (struct radv_subpass_attachment[]) { subpass->color_attachments[clear_att->colorAttachment] }, - .depth_stencil_attachment = (struct radv_subpass_attachment) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED } + .depth_stencil_attachment = NULL, }; radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass); @@ -702,7 +702,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, 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 = subpass->depth_stencil_attachment->attachment; VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; VkImageAspectFlags aspects = clear_att->aspectMask; const struct radv_image_view *iview = fb->attachments[pass_att].attachment; @@ -731,7 +731,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, iview, samples_log2, aspects, - subpass->depth_stencil_attachment.layout, + subpass->depth_stencil_attachment->layout, clear_rect, clear_value); if (!pipeline) @@ -741,7 +741,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, pipeline); if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, - subpass->depth_stencil_attachment.layout, + subpass->depth_stencil_attachment->layout, clear_rect, clear_value)) radv_update_ds_clear_metadata(cmd_buffer, iview->image, clear_value, aspects); @@ -1536,8 +1536,8 @@ 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; - VkImageLayout image_layout = subpass->depth_stencil_attachment.layout; + const uint32_t pass_att = subpass->depth_stencil_attachment->attachment; + VkImageLayout image_layout = subpass->depth_stencil_attachment->layout; const struct radv_image_view *iview = fb->attachments[pass_att].attachment; VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; @@ -1580,7 +1580,10 @@ radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) return true; } - a = cmd_state->subpass->depth_stencil_attachment.attachment; + if (!cmd_state->subpass->depth_stencil_attachment) + return false; + + a = cmd_state->subpass->depth_stencil_attachment->attachment; return radv_attachment_needs_clear(cmd_state, a); } @@ -1649,17 +1652,19 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) &post_flush); } - uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; - if (radv_attachment_needs_clear(cmd_state, ds)) { - VkClearAttachment clear_att = { - .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, - .clearValue = cmd_state->attachments[ds].clear_value, - }; - - radv_subpass_clear_attachment(cmd_buffer, - &cmd_state->attachments[ds], - &clear_att, &pre_flush, - &post_flush); + if (cmd_state->subpass->depth_stencil_attachment) { + uint32_t ds = cmd_state->subpass->depth_stencil_attachment->attachment; + if (radv_attachment_needs_clear(cmd_state, ds)) { + VkClearAttachment clear_att = { + .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, + .clearValue = cmd_state->attachments[ds].clear_value, + }; + + radv_subpass_clear_attachment(cmd_buffer, + &cmd_state->attachments[ds], + &clear_att, &pre_flush, + &post_flush); + } } radv_meta_restore(&saved_state, cmd_buffer); diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c index 821f47c9671..baa5746b8ab 100644 --- a/src/amd/vulkan/radv_meta_resolve.c +++ b/src/amd/vulkan/radv_meta_resolve.c @@ -675,7 +675,7 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer) struct radv_subpass resolve_subpass = { .color_count = 2, .color_attachments = (struct radv_subpass_attachment[]) { src_att, dest_att }, - .depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED }, + .depth_stencil_attachment = NULL, }; radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass); diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c index 47af4bb1d86..1ab7ece8dfb 100644 --- a/src/amd/vulkan/radv_meta_resolve_fs.c +++ b/src/amd/vulkan/radv_meta_resolve_fs.c @@ -620,7 +620,7 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) struct radv_subpass resolve_subpass = { .color_count = 1, .color_attachments = (struct radv_subpass_attachment[]) { dest_att }, - .depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED }, + .depth_stencil_attachment = NULL, }; radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass); diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c index 3a70006f6bb..1102ef689b2 100644 --- a/src/amd/vulkan/radv_pass.c +++ b/src/amd/vulkan/radv_pass.c @@ -28,6 +28,32 @@ #include "vk_util.h" +static void +radv_render_pass_compile(struct radv_render_pass *pass) +{ + for (uint32_t i = 0; i < pass->subpass_count; i++) { + struct radv_subpass *subpass = &pass->subpasses[i]; + + /* We don't allow depth_stencil_attachment to be non-NULL and + * be VK_ATTACHMENT_UNUSED. This way something can just check + * for NULL and be guaranteed that they have a valid + * attachment. + */ + if (subpass->depth_stencil_attachment && + subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED) + subpass->depth_stencil_attachment = NULL; + } +} + +static unsigned +radv_num_subpass_attachments(const VkSubpassDescription *desc) +{ + return desc->inputAttachmentCount + + desc->colorAttachmentCount + + (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + + (desc->pDepthStencilAttachment != NULL); +} + VkResult radv_CreateRenderPass( VkDevice _device, const VkRenderPassCreateInfo* pCreateInfo, @@ -82,13 +108,8 @@ VkResult radv_CreateRenderPass( uint32_t subpass_attachment_count = 0; struct radv_subpass_attachment *p; for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i]; - subpass_attachment_count += - desc->inputAttachmentCount + - desc->colorAttachmentCount + - (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + - (desc->pDepthStencilAttachment != NULL); + radv_num_subpass_attachments(&pCreateInfo->pSubpasses[i]); } if (subpass_attachment_count) { @@ -111,6 +132,9 @@ VkResult radv_CreateRenderPass( subpass->input_count = desc->inputAttachmentCount; subpass->color_count = desc->colorAttachmentCount; + subpass->attachment_count = radv_num_subpass_attachments(desc); + subpass->attachments = p; + if (multiview_info) subpass->view_mask = multiview_info->pViewMasks[i]; @@ -159,15 +183,15 @@ VkResult radv_CreateRenderPass( } if (desc->pDepthStencilAttachment) { - subpass->depth_stencil_attachment = (struct radv_subpass_attachment) { + subpass->depth_stencil_attachment = p++; + + *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) { .attachment = desc->pDepthStencilAttachment->attachment, .layout = desc->pDepthStencilAttachment->layout, }; if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples; } - } else { - subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; } subpass->max_sample_count = MAX2(color_sample_count, @@ -197,11 +221,22 @@ VkResult radv_CreateRenderPass( } } + radv_render_pass_compile(pass); + *pRenderPass = radv_render_pass_to_handle(pass); return VK_SUCCESS; } +static unsigned +radv_num_subpass_attachments2(const VkSubpassDescription2KHR *desc) +{ + return desc->inputAttachmentCount + + desc->colorAttachmentCount + + (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + + (desc->pDepthStencilAttachment != NULL); +} + VkResult radv_CreateRenderPass2KHR( VkDevice _device, const VkRenderPassCreateInfo2KHR* pCreateInfo, @@ -245,13 +280,8 @@ VkResult radv_CreateRenderPass2KHR( uint32_t subpass_attachment_count = 0; struct radv_subpass_attachment *p; for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i]; - subpass_attachment_count += - desc->inputAttachmentCount + - desc->colorAttachmentCount + - (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + - (desc->pDepthStencilAttachment != NULL); + radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); } if (subpass_attachment_count) { @@ -274,6 +304,8 @@ VkResult radv_CreateRenderPass2KHR( subpass->input_count = desc->inputAttachmentCount; subpass->color_count = desc->colorAttachmentCount; + subpass->attachment_count = radv_num_subpass_attachments2(desc); + subpass->attachments = p; subpass->view_mask = desc->viewMask; if (desc->inputAttachmentCount > 0) { @@ -321,15 +353,15 @@ VkResult radv_CreateRenderPass2KHR( } if (desc->pDepthStencilAttachment) { - subpass->depth_stencil_attachment = (struct radv_subpass_attachment) { + subpass->depth_stencil_attachment = p++; + + *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) { .attachment = desc->pDepthStencilAttachment->attachment, .layout = desc->pDepthStencilAttachment->layout, }; if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples; } - } else { - subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; } subpass->max_sample_count = MAX2(color_sample_count, @@ -359,6 +391,8 @@ VkResult radv_CreateRenderPass2KHR( } } + radv_render_pass_compile(pass); + *pRenderPass = radv_render_pass_to_handle(pass); return VK_SUCCESS; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 138e153f9a4..c96f86bff63 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -966,11 +966,11 @@ radv_pipeline_out_of_order_rast(struct radv_pipeline *pipeline, }; if (pCreateInfo->pDepthStencilState && - subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { + subpass->depth_stencil_attachment) { const VkPipelineDepthStencilStateCreateInfo *vkds = pCreateInfo->pDepthStencilState; struct radv_render_pass_attachment *attachment = - pass->attachments + subpass->depth_stencil_attachment.attachment; + pass->attachments + subpass->depth_stencil_attachment->attachment; bool has_stencil = vk_format_is_stencil(attachment->format); struct radv_dsa_order_invariance order_invariance[2]; struct radv_shader_variant *ps = @@ -1401,8 +1401,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, * disabled or if the subpass of the render pass the pipeline is created * against does not use a depth/stencil attachment. */ - if (needed_states && - subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { + if (needed_states && subpass->depth_stencil_attachment) { assert(pCreateInfo->pDepthStencilState); if (states & RADV_DYNAMIC_DEPTH_BOUNDS) { @@ -2506,8 +2505,8 @@ radv_compute_bin_size(struct radv_pipeline *pipeline, const VkGraphicsPipelineCr extent = color_entry->extent; - if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { - struct radv_render_pass_attachment *attachment = pass->attachments + subpass->depth_stencil_attachment.attachment; + if (subpass->depth_stencil_attachment) { + struct radv_render_pass_attachment *attachment = pass->attachments + subpass->depth_stencil_attachment->attachment; /* Coefficients taken from AMDVLK */ unsigned depth_coeff = vk_format_is_depth(attachment->format) ? 5 : 0; @@ -2598,8 +2597,8 @@ radv_pipeline_generate_depth_stencil_state(struct radeon_cmdbuf *ctx_cs, uint32_t db_render_control = 0, db_render_override2 = 0; uint32_t db_render_override = 0; - if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) - attachment = pass->attachments + subpass->depth_stencil_attachment.attachment; + if (subpass->depth_stencil_attachment) + attachment = pass->attachments + subpass->depth_stencil_attachment->attachment; bool has_depth_attachment = attachment && vk_format_is_depth(attachment->format); bool has_stencil_attachment = attachment && vk_format_is_stencil(attachment->format); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index e2849b3a901..4863841a0ac 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1815,12 +1815,15 @@ struct radv_subpass_attachment { }; struct radv_subpass { + uint32_t attachment_count; + struct radv_subpass_attachment * attachments; + uint32_t input_count; uint32_t color_count; struct radv_subpass_attachment * input_attachments; struct radv_subpass_attachment * color_attachments; struct radv_subpass_attachment * resolve_attachments; - struct radv_subpass_attachment depth_stencil_attachment; + struct radv_subpass_attachment * depth_stencil_attachment; /** Subpass has at least one resolve attachment */ bool has_resolve; -- 2.30.2