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 <[email protected]>
---
 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 d64eee80f65..a4b611f18d3 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.20.1

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to