radv: store the list of attachments for every subpass
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 29 Jan 2019 21:18:51 +0000 (22:18 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 4 Feb 2019 12:17:54 +0000 (13:17 +0100)
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 <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_meta_clear.c
src/amd/vulkan/radv_meta_resolve.c
src/amd/vulkan/radv_meta_resolve_fs.c
src/amd/vulkan/radv_pass.c
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_private.h

index 003dcbd5fb28df9da44c7cd5de4596a82d694a4a..440f09a363c1f2bbecc6943d722bedb93af042dc 100644 (file)
@@ -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);
index 06f25aa46d7972d7347507e04c3ec106dcd6f45a..c68ce1ee8a80fbacbef93a1ce2e39a4ccfa24b74 100644 (file)
@@ -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);
index 821f47c96718bb3a122cb5b2853e9be6ff358bec..baa5746b8ab9021a8fa61244dae3dcd05c216d1d 100644 (file)
@@ -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);
index 47af4bb1d86c2451f17ed4ec6506dcf989ea3281..1ab7ece8dfb6bfd691a5fc05b192850f290ed98d 100644 (file)
@@ -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);
index 3a70006f6bb5a67fb66bcecc0f608d174ae450dd..1102ef689b2ac5a9a61c68f6026b83882589622e 100644 (file)
 
 #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;
index 138e153f9a4f10d97d901eb3647db3739769cb89..c96f86bff63e21e6fecff8dde3b846e6af2a3080 100644 (file)
@@ -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);
index e2849b3a9015639bc8a6f3ff83030ac34b8a2e69..4863841a0ac2878cb9a1b90703bd65ff76aff669 100644 (file)
@@ -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;