mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 17:30:12 +01:00
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 <jonathan@marek.ca> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4588>
This commit is contained in:
parent
e72201c787
commit
44c6c145da
4 changed files with 89 additions and 59 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue