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:
parent
df4b5914cd
commit
d2ad4c739c
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue