From: Jonathan Marek Date: Thu, 9 Apr 2020 23:32:19 +0000 (-0400) Subject: turnip: improve GMEM load/store logic X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=44c6c145daadf618607abb997f20608e820daee0;p=mesa.git turnip: improve GMEM load/store logic Determine load/store at renderpass creation time. This also fixes behavior with S8_UINT. Signed-off-by: Jonathan Marek Part-of: --- diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c index c07e7e0bd0e..621449285d6 100644 --- a/src/freedreno/vulkan/tu_clear_blit.c +++ b/src/freedreno/vulkan/tu_clear_blit.c @@ -2123,17 +2123,14 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd, &cmd->state.pass->attachments[a]; uint8_t mask = 0; - if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) + if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT) mask = 0xf; + if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT) + mask |= 0x7; + if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT) + mask |= 0x8; - if (attachment->format == VK_FORMAT_D24_UNORM_S8_UINT) { - mask &= 0x7; - if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) - mask |= 0x8; - } - - /* gmem_offset<0 means it isn't used by any subpass and shouldn't be cleared */ - if (attachment->gmem_offset < 0 || !mask) + if (!mask) return; const struct blit_ops *ops = &r2d_ops; @@ -2160,18 +2157,13 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd, &cmd->state.pass->attachments[a]; unsigned clear_mask = 0; - /* note: this means it isn't used by any subpass and shouldn't be cleared anyway */ - if (attachment->gmem_offset < 0) - return; - - if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) + if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT) clear_mask = 0xf; + if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT) + clear_mask |= 0x7; + if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT) + clear_mask |= 0x8; - if (vk_format_has_stencil(attachment->format)) { - clear_mask &= 0x7; - if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) - clear_mask |= 0x8; - } if (!clear_mask) return; @@ -2185,7 +2177,7 @@ static void tu_emit_blit(struct tu_cmd_buffer *cmd, struct tu_cs *cs, const struct tu_image_view *iview, - struct tu_render_pass_attachment *attachment, + const struct tu_render_pass_attachment *attachment, bool resolve) { tu_cs_emit_regs(cs, @@ -2246,28 +2238,18 @@ blit_can_resolve(VkFormat format) } void -tu_emit_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a) -{ - tu_emit_blit(cmd, cs, - cmd->state.framebuffer->attachments[a].attachment, - &cmd->state.pass->attachments[a], - false); -} - -void -tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a) +tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, + struct tu_cs *cs, + uint32_t a, + bool force_load) { + const struct tu_image_view *iview = + cmd->state.framebuffer->attachments[a].attachment; const struct tu_render_pass_attachment *attachment = &cmd->state.pass->attachments[a]; - if (attachment->gmem_offset < 0) - return; - - if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_LOAD || - (vk_format_has_stencil(attachment->format) && - attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_LOAD)) { - tu_emit_load_gmem_attachment(cmd, cs, a); - } + if (attachment->load || force_load) + tu_emit_blit(cmd, cs, iview, attachment, false); } void @@ -2282,7 +2264,7 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_image_view *iview = cmd->state.framebuffer->attachments[a].attachment; struct tu_render_pass_attachment *src = &cmd->state.pass->attachments[gmem_a]; - if (dst->store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) + if (!dst->store) return; uint32_t x1 = render_area->offset.x; diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 11269c2a98c..b6ca849c80c 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -1123,7 +1123,7 @@ tu_emit_load_clear(struct tu_cmd_buffer *cmd, tu6_emit_blit_scissor(cmd, cs, true); for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i) - tu_load_gmem_attachment(cmd, cs, i); + tu_load_gmem_attachment(cmd, cs, i, false); tu6_emit_blit_scissor(cmd, cs, false); @@ -2362,7 +2362,7 @@ tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) * if it is, should be doing a GMEM->GMEM resolve instead of GMEM->MEM->GMEM.. */ tu_finishme("missing GMEM->GMEM resolve path\n"); - tu_emit_load_gmem_attachment(cmd, cs, a); + tu_load_gmem_attachment(cmd, cs, a, true); } } diff --git a/src/freedreno/vulkan/tu_pass.c b/src/freedreno/vulkan/tu_pass.c index b14eab022fa..7d537973e5e 100644 --- a/src/freedreno/vulkan/tu_pass.c +++ b/src/freedreno/vulkan/tu_pass.c @@ -102,6 +102,53 @@ create_render_pass_common(struct tu_render_pass *pass, subpass->srgb_cntl |= 1 << i; } } + + /* disable unused attachments */ + for (uint32_t i = 0; i < pass->attachment_count; i++) { + struct tu_render_pass_attachment *att = &pass->attachments[i]; + if (att->gmem_offset < 0) { + att->clear_mask = 0; + att->load = false; + } + } +} + +static void +attachment_set_ops(struct tu_render_pass_attachment *att, + VkAttachmentLoadOp load_op, + VkAttachmentLoadOp stencil_load_op, + VkAttachmentStoreOp store_op, + VkAttachmentStoreOp stencil_store_op) +{ + /* load/store ops */ + att->clear_mask = + (load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ? VK_IMAGE_ASPECT_COLOR_BIT : 0; + att->load = (load_op == VK_ATTACHMENT_LOAD_OP_LOAD); + att->store = (store_op == VK_ATTACHMENT_STORE_OP_STORE); + + bool stencil_clear = (stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR); + bool stencil_load = (stencil_load_op == VK_ATTACHMENT_LOAD_OP_LOAD); + bool stencil_store = (stencil_store_op == VK_ATTACHMENT_STORE_OP_STORE); + + switch (att->format) { + case VK_FORMAT_D24_UNORM_S8_UINT: /* || stencil load/store */ + if (att->clear_mask) + att->clear_mask = VK_IMAGE_ASPECT_DEPTH_BIT; + if (stencil_clear) + att->clear_mask |= VK_IMAGE_ASPECT_STENCIL_BIT; + if (stencil_load) + att->load = true; + if (stencil_store) + att->store = true; + break; + case VK_FORMAT_S8_UINT: /* replace load/store with stencil load/store */ + att->clear_mask = stencil_clear ? VK_IMAGE_ASPECT_COLOR_BIT : 0; + att->load = stencil_load; + att->store = stencil_store; + break; + default: + break; + } } VkResult @@ -138,13 +185,13 @@ tu_CreateRenderPass(VkDevice _device, att->format = pCreateInfo->pAttachments[i].format; att->samples = pCreateInfo->pAttachments[i].samples; att->cpp = vk_format_get_blocksize(att->format) * att->samples; - att->load_op = pCreateInfo->pAttachments[i].loadOp; - att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; - att->store_op = pCreateInfo->pAttachments[i].storeOp; - if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE && - vk_format_has_stencil(att->format)) - att->store_op = VK_ATTACHMENT_STORE_OP_STORE; att->gmem_offset = -1; + + attachment_set_ops(att, + pCreateInfo->pAttachments[i].loadOp, + pCreateInfo->pAttachments[i].stencilLoadOp, + pCreateInfo->pAttachments[i].storeOp, + pCreateInfo->pAttachments[i].stencilStoreOp); } uint32_t subpass_attachment_count = 0; @@ -266,14 +313,13 @@ tu_CreateRenderPass2(VkDevice _device, att->format = pCreateInfo->pAttachments[i].format; att->samples = pCreateInfo->pAttachments[i].samples; att->cpp = vk_format_get_blocksize(att->format) * att->samples; - att->load_op = pCreateInfo->pAttachments[i].loadOp; - att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; - att->store_op = pCreateInfo->pAttachments[i].storeOp; - att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; - if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE && - vk_format_has_stencil(att->format)) - att->store_op = VK_ATTACHMENT_STORE_OP_STORE; att->gmem_offset = -1; + + attachment_set_ops(att, + pCreateInfo->pAttachments[i].loadOp, + pCreateInfo->pAttachments[i].stencilLoadOp, + pCreateInfo->pAttachments[i].storeOp, + pCreateInfo->pAttachments[i].stencilStoreOp); } uint32_t subpass_attachment_count = 0; struct tu_subpass_attachment *p; diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 4953075375f..eb026998293 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1319,7 +1319,10 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd, const VkRenderPassBeginInfo *info); void -tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a); +tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, + struct tu_cs *cs, + uint32_t a, + bool force_load); /* expose this function to be able to emit load without checking LOAD_OP */ void @@ -1590,10 +1593,9 @@ struct tu_render_pass_attachment VkFormat format; uint32_t samples; uint32_t cpp; - VkAttachmentLoadOp load_op; - VkAttachmentLoadOp stencil_load_op; - VkAttachmentStoreOp store_op; - VkAttachmentStoreOp stencil_store_op; + VkImageAspectFlags clear_mask; + bool load; + bool store; int32_t gmem_offset; };