aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonathan Marek <[email protected]>2020-04-09 19:32:19 -0400
committerMarge Bot <[email protected]>2020-04-22 17:45:33 +0000
commit44c6c145daadf618607abb997f20608e820daee0 (patch)
treeb652082698fd92c65e124169c8f3e48f59eb45af /src
parente72201c7873ea22dadf8d1775f97400a435a8b9a (diff)
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 <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4588>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/vulkan/tu_clear_blit.c60
-rw-r--r--src/freedreno/vulkan/tu_cmd_buffer.c4
-rw-r--r--src/freedreno/vulkan/tu_pass.c72
-rw-r--r--src/freedreno/vulkan/tu_private.h12
4 files changed, 89 insertions, 59 deletions
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;
};