tu/lrz: Do not use framebuffer when inheriting LRZ

The only thing it's used for is to get the image view, and we can't rely
on it existing anyway. With dynamic rendering, we only have the format
of the attachments and sample count, so moving forward we can't rely on
anything other than that.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17378>
This commit is contained in:
Connor Abbott 2022-06-29 11:33:56 +02:00 committed by Marge Bot
parent df4b5914cd
commit d2ad4c739c
3 changed files with 61 additions and 16 deletions

View File

@ -1772,13 +1772,11 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
}
if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
TU_FROM_HANDLE(tu_framebuffer, fb, pBeginInfo->pInheritanceInfo->framebuffer);
cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
cmd_buffer->state.subpass =
&cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
tu_lrz_begin_secondary_cmdbuf(cmd_buffer, fb);
tu_lrz_begin_secondary_cmdbuf(cmd_buffer);
} else {
/* When executing in the middle of another command buffer, the CCU
* state is unknown.

View File

@ -202,8 +202,11 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
const struct tu_render_pass_attachment *att,
const struct tu_image_view *view)
{
if (!view->image->lrz_height)
if (!view->image->lrz_height) {
assert((cmd->device->instance->debug_flags & TU_DEBUG_NOLRZ) ||
!vk_format_has_depth(att->format));
return;
}
bool clears_depth = att->clear_mask &
(VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
@ -213,10 +216,17 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
if (!has_gpu_tracking && !clears_depth)
return;
/* We need to always have an LRZ view just to disable it if there is a
* depth attachment, there are any secondaries, and GPU tracking is
* enabled, in order not to rely on loadOp state which doesn't exist with
* dynamic rendering in secondaries. Otherwise the secondary will have LRZ
* enabled and there will be a NULL/garbage LRZ buffer.
*/
cmd->state.lrz.image_view = view;
if (!clears_depth && !att->load)
return;
cmd->state.lrz.image_view = view;
cmd->state.lrz.valid = true;
cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN;
/* Be optimistic and unconditionally enable fast-clear in
@ -228,6 +238,43 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
cmd->state.lrz.reuse_previous_state = !clears_depth;
}
/* Note: if we enable LRZ here, then tu_lrz_init_state() must at least set
* lrz.image_view, so that an LRZ buffer is present (even if LRZ is
* dynamically disabled).
*/
static void
tu_lrz_init_secondary(struct tu_cmd_buffer *cmd,
const struct tu_render_pass_attachment *att)
{
bool has_gpu_tracking =
cmd->device->physical_device->info->a6xx.has_lrz_dir_tracking;
if (!has_gpu_tracking)
return;
if (cmd->device->instance->debug_flags & TU_DEBUG_NOLRZ)
return;
if (!vk_format_has_depth(att->format))
return;
cmd->state.lrz.valid = true;
cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN;
cmd->state.lrz.gpu_dir_tracking = has_gpu_tracking;
/* We may not have the depth attachment when executing in a secondary
* inside a render pass. This means we have to be even more optimistic than
* the normal case and enable fast clear even if the depth image doesn't
* support it.
*/
cmd->state.lrz.fast_clear = true;
/* These are not used inside secondaries */
cmd->state.lrz.image_view = NULL;
cmd->state.lrz.reuse_previous_state = false;
}
void
tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
const VkRenderPassBeginInfo *pRenderPassBegin)
@ -257,7 +304,7 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
}
/* Track LRZ valid state */
cmd->state.lrz.valid = false;
memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
uint32_t a = cmd->state.subpass->depth_stencil_attachment.attachment;
if (a != VK_ATTACHMENT_UNUSED) {
const struct tu_render_pass_attachment *att = &cmd->state.pass->attachments[a];
@ -273,28 +320,29 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
}
if (!cmd->state.lrz.valid) {
memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
tu6_emit_lrz_buffer(&cmd->cs, NULL);
}
}
void
tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd,
struct tu_framebuffer *fb)
tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd)
{
memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
uint32_t a = cmd->state.subpass->depth_stencil_attachment.attachment;
if (a != VK_ATTACHMENT_UNUSED &&
cmd->device->physical_device->info->a6xx.has_lrz_dir_tracking) {
if (a != VK_ATTACHMENT_UNUSED) {
const struct tu_render_pass_attachment *att = &cmd->state.pass->attachments[a];
struct tu_image_view *view = fb->attachments[a].attachment;
tu_lrz_init_state(cmd, att, view);
tu_lrz_init_secondary(cmd, att);
}
}
void
tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
{
/* TODO: If lrz was never valid for the entire renderpass, we could exit
* early here. Sometimes we know this ahead of time and null out
* image_view, but with LOAD_OP_DONT_CARE this only happens if there were
* no secondaries.
*/
if (!cmd->state.lrz.image_view)
return;

View File

@ -1591,8 +1591,7 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
const VkRenderPassBeginInfo *pRenderPassBegin);
void
tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd,
struct tu_framebuffer *fb);
tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd);
void
tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs);