From df34b8fac64df210caee7447927725f22ece8cf3 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Tue, 28 Jan 2020 16:53:54 +0100 Subject: [PATCH] v3dv: compute subpass ranges for attachments at render pass creation time Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 87 +++++---------------------- src/broadcom/vulkan/v3dv_pass.c | 37 ++++++++++++ src/broadcom/vulkan/v3dv_private.h | 4 +- 3 files changed, 55 insertions(+), 73 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index a312094c8d3..e07c3d2c43d 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -613,55 +613,10 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer, } } -/* Identifies the first and last subpasses that use each attachment in - * the current render pass. - * - * FIXME: consider doing this at render pass creation time and store it - * in the render pass data. - */ -static void -cmd_buffer_find_subpass_range_for_attachments(struct v3dv_cmd_buffer *cmd_buffer) -{ - struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; - const struct v3dv_render_pass *pass = state->pass; - - for (uint32_t i = 0; i < pass->attachment_count; i++) { - state->attachments[i].first_subpass = pass->subpass_count - 1; - state->attachments[i].last_subpass = 0; - } - - for (uint32_t i = 0; i < pass->subpass_count; i++) { - const struct v3dv_subpass *subpass = &pass->subpasses[i]; - - for (uint32_t j = 0; j < subpass->color_count; j++) { - uint32_t attachment_idx = subpass->color_attachments[j].attachment; - if (attachment_idx == VK_ATTACHMENT_UNUSED) - continue; - - if (i < state->attachments[attachment_idx].first_subpass) - state->attachments[attachment_idx].first_subpass = i; - if (i > state->attachments[attachment_idx].last_subpass) - state->attachments[attachment_idx].last_subpass = i; - } - - uint32_t ds_attachment_idx = subpass->ds_attachment.attachment; - if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { - if (i < state->attachments[ds_attachment_idx].first_subpass) - state->attachments[ds_attachment_idx].first_subpass = i; - if (i > state->attachments[ds_attachment_idx].last_subpass) - state->attachments[ds_attachment_idx].last_subpass = i; - } - - /* FIXME: input/resolve attachments */ - } -} - static void cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer, const VkRenderPassBeginInfo *pRenderPassBegin) { - cmd_buffer_find_subpass_range_for_attachments(cmd_buffer); - cmd_buffer_state_set_clear_values(cmd_buffer, pRenderPassBegin->clearValueCount, pRenderPassBegin->pClearValues); @@ -801,8 +756,8 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer, { const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; const struct v3dv_framebuffer *framebuffer = state->framebuffer; - const struct v3dv_subpass *subpass = - &state->pass->subpasses[state->subpass_idx]; + const struct v3dv_render_pass *pass = state->pass; + const struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx]; for (uint32_t i = 0; i < subpass->color_count; i++) { uint32_t attachment_idx = subpass->color_attachments[i].attachment; @@ -813,9 +768,6 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer, const struct v3dv_render_pass_attachment *attachment = &state->pass->attachments[attachment_idx]; - const struct v3dv_cmd_buffer_attachment_state *attachment_state = - &state->attachments[attachment_idx]; - /* According to the Vulkan spec: * * "The load operation for each sample in an attachment happens before @@ -827,9 +779,9 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer, * After that, we always want to load so we don't lose any rendering done * by a previous subpass to the same attachment. */ - assert(state->job->first_subpass >= attachment_state->first_subpass); + assert(state->job->first_subpass >= attachment->first_subpass); bool needs_load = - state->job->first_subpass > attachment_state->first_subpass || + state->job->first_subpass > attachment->first_subpass || attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD; if (needs_load) { @@ -843,12 +795,10 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer, if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { const struct v3dv_render_pass_attachment *ds_attachment = &state->pass->attachments[ds_attachment_idx]; - const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state = - &state->attachments[ds_attachment_idx]; - assert(state->job->first_subpass >= ds_attachment_state->first_subpass); + assert(state->job->first_subpass >= ds_attachment->first_subpass); bool needs_load = - state->job->first_subpass > ds_attachment_state->first_subpass || + state->job->first_subpass > ds_attachment->first_subpass || ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD; if (needs_load) { @@ -920,21 +870,18 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer, const struct v3dv_render_pass_attachment *attachment = &state->pass->attachments[attachment_idx]; - const struct v3dv_cmd_buffer_attachment_state *attachment_state = - &state->attachments[attachment_idx]; - - assert(state->job->first_subpass >= attachment_state->first_subpass); - assert(state->subpass_idx >= attachment_state->first_subpass); - assert(state->subpass_idx <= attachment_state->last_subpass); + assert(state->job->first_subpass >= attachment->first_subpass); + assert(state->subpass_idx >= attachment->first_subpass); + assert(state->subpass_idx <= attachment->last_subpass); /* Only clear once on the first subpass that uses the attachment */ bool needs_clear = - state->job->first_subpass == attachment_state->first_subpass && + state->job->first_subpass == attachment->first_subpass && attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR; /* Skip the last store if it is not required */ bool needs_store = - state->subpass_idx < attachment_state->last_subpass || + state->subpass_idx < attachment->last_subpass || attachment->desc.storeOp == VK_ATTACHMENT_STORE_OP_STORE || needs_clear; @@ -965,21 +912,19 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer, if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { const struct v3dv_render_pass_attachment *ds_attachment = &state->pass->attachments[ds_attachment_idx]; - const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state = - &state->attachments[ds_attachment_idx]; - assert(state->job->first_subpass >= ds_attachment_state->first_subpass); - assert(state->subpass_idx >= ds_attachment_state->first_subpass); - assert(state->subpass_idx <= ds_attachment_state->last_subpass); + assert(state->job->first_subpass >= ds_attachment->first_subpass); + assert(state->subpass_idx >= ds_attachment->first_subpass); + assert(state->subpass_idx <= ds_attachment->last_subpass); /* Only clear once on the first subpass that uses the attachment */ needs_ds_clear = - state->job->first_subpass == ds_attachment_state->first_subpass && + state->job->first_subpass == ds_attachment->first_subpass && ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR; /* Skip the last store if it is not required */ bool needs_ds_store = - state->subpass_idx < ds_attachment_state->last_subpass || + state->subpass_idx < ds_attachment->last_subpass || ds_attachment->desc.storeOp == VK_ATTACHMENT_STORE_OP_STORE || needs_ds_clear; diff --git a/src/broadcom/vulkan/v3dv_pass.c b/src/broadcom/vulkan/v3dv_pass.c index 7ec389e1f70..a84ff73b29a 100644 --- a/src/broadcom/vulkan/v3dv_pass.c +++ b/src/broadcom/vulkan/v3dv_pass.c @@ -32,6 +32,41 @@ num_subpass_attachments(const VkSubpassDescription *desc) (desc->pDepthStencilAttachment != NULL); } +static void +pass_find_subpass_range_for_attachments(struct v3dv_render_pass *pass) +{ + for (uint32_t i = 0; i < pass->attachment_count; i++) { + pass->attachments[i].first_subpass = pass->subpass_count - 1; + pass->attachments[i].last_subpass = 0; + } + + for (uint32_t i = 0; i < pass->subpass_count; i++) { + const struct v3dv_subpass *subpass = &pass->subpasses[i]; + + for (uint32_t j = 0; j < subpass->color_count; j++) { + uint32_t attachment_idx = subpass->color_attachments[j].attachment; + if (attachment_idx == VK_ATTACHMENT_UNUSED) + continue; + + if (i < pass->attachments[attachment_idx].first_subpass) + pass->attachments[attachment_idx].first_subpass = i; + if (i > pass->attachments[attachment_idx].last_subpass) + pass->attachments[attachment_idx].last_subpass = i; + } + + uint32_t ds_attachment_idx = subpass->ds_attachment.attachment; + if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { + if (i < pass->attachments[ds_attachment_idx].first_subpass) + pass->attachments[ds_attachment_idx].first_subpass = i; + if (i > pass->attachments[ds_attachment_idx].last_subpass) + pass->attachments[ds_attachment_idx].last_subpass = i; + } + + /* FIXME: input/resolve attachments */ + } +} + + VkResult v3dv_CreateRenderPass(VkDevice _device, const VkRenderPassCreateInfo *pCreateInfo, @@ -137,6 +172,8 @@ v3dv_CreateRenderPass(VkDevice _device, } } + pass_find_subpass_range_for_attachments(pass); + /* FIXME: handle subpass dependencies */ *pRenderPass = v3dv_render_pass_to_handle(pass); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index d286cb854d7..0cd0c528ccc 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -358,6 +358,8 @@ struct v3dv_subpass { struct v3dv_render_pass_attachment { VkAttachmentDescription desc; + uint32_t first_subpass; + uint32_t last_subpass; }; struct v3dv_render_pass { @@ -412,8 +414,6 @@ union v3dv_clear_value { struct v3dv_cmd_buffer_attachment_state { union v3dv_clear_value clear_value; - uint32_t first_subpass; - uint32_t last_subpass; }; struct v3dv_viewport_state {