From 9d20241a03108e60f0ddc6a331a8032b2bff22bb Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Mon, 7 Apr 2025 15:07:30 +0200 Subject: [PATCH] tu/lrz: Fix DONT_CARE not resulting in disabled LRZ - LOAD results in reusing LRZ from previous renderpasses. - CLEAR clears LRZ. - DONT_CARE doesn't clear and doesn't load, so LRZ should be disabled, that was also the initial idea in code, but conditions didn't work out and are now fixed. Fixes glcts tests: KHR-GL46.packed_depth_stencil.blit.depth24_stencil8 KHR-GL46.packed_depth_stencil.blit.depth32f_stencil8 KHR-GLES3.packed_depth_stencil.blit.depth24_stencil8 KHR-GLES3.packed_depth_stencil.blit.depth32f_stencil8 Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/vulkan/tu_lrz.cc | 29 ++++++++++++++++------------- src/freedreno/vulkan/tu_lrz.h | 3 ++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/freedreno/vulkan/tu_lrz.cc b/src/freedreno/vulkan/tu_lrz.cc index b26cfe3d7c9..a195d66cd6b 100644 --- a/src/freedreno/vulkan/tu_lrz.cc +++ b/src/freedreno/vulkan/tu_lrz.cc @@ -222,6 +222,7 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd, return; cmd->state.lrz.valid = true; + cmd->state.lrz.valid_at_start = true; cmd->state.lrz.disable_write_for_rp = false; cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN; /* Be optimistic and unconditionally enable fast-clear in @@ -256,6 +257,7 @@ tu_lrz_init_secondary(struct tu_cmd_buffer *cmd, return; cmd->state.lrz.valid = true; + cmd->state.lrz.valid_at_start = true; cmd->state.lrz.disable_write_for_rp = false; cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN; cmd->state.lrz.gpu_dir_tracking = has_gpu_tracking; @@ -352,7 +354,7 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd) /* Track LRZ valid state */ tu_lrz_begin_resumed_renderpass(cmd); - if (!cmd->state.lrz.valid || TU_DEBUG(NOLRZ)) { + if (!cmd->state.lrz.valid_at_start || TU_DEBUG(NOLRZ)) { tu6_write_lrz_cntl(cmd, &cmd->cs, {}); tu6_emit_lrz_buffer(&cmd->cs, NULL); } @@ -397,15 +399,19 @@ tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs) return; } - if (lrz->disable_for_rp) { - /* We may deem necessary to disable LRZ for the whole renderpass. + if (!lrz->valid_at_start) { + /* If LRZ was never valid so disable it manually here. * This is accomplished by making later GRAS_LRZ_CNTL (in binning pass) * to fail the comparison of depth views. - * TODO: Find if there are conditions where it is beneficial. */ - tu6_disable_lrz_via_depth_view(cmd, cs); - tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = 0)); - } else if (lrz->fast_clear || lrz->gpu_dir_tracking) { + if (lrz->gpu_dir_tracking) { + tu6_disable_lrz_via_depth_view(cmd, cs); + tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = 0)); + } + return; + } + + if (lrz->fast_clear || lrz->gpu_dir_tracking) { if (lrz->gpu_dir_tracking) { tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = lrz->image_view->view.GRAS_LRZ_DEPTH_VIEW)); @@ -426,7 +432,7 @@ tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_emit_event_write(cmd, cs, FD_LRZ_CLEAR); } - if (!lrz->fast_clear && !lrz->disable_for_rp) { + if (!lrz->fast_clear) { tu6_clear_lrz(cmd, cs, lrz->image_view->image, &lrz->depth_clear_value); /* Even though we disable fast-clear we still have to dirty * fast-clear buffer because both secondary cmdbufs and following @@ -456,7 +462,7 @@ tu_lrz_before_tile(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu6_emit_lrz_buffer(cs, lrz->image_view->image); if (lrz->gpu_dir_tracking) { - if (lrz->disable_for_rp) { + if (!lrz->valid_at_start) { /* Make sure we fail the comparison of depth views */ tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = 0)); } else { @@ -493,7 +499,7 @@ tu_lrz_tiling_end(struct tu_cmd_buffer *cmd, struct tu_cs *cs) /* If we haven't disabled LRZ during renderpass, we need to disable it here * for next renderpass to not use invalid LRZ values. */ - if (cmd->state.lrz.gpu_dir_tracking && !cmd->state.lrz.disable_for_rp && + if (cmd->state.lrz.gpu_dir_tracking && cmd->state.lrz.valid_at_start && !cmd->state.lrz.valid) { tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW( .base_layer = 0b11111111111, @@ -686,9 +692,6 @@ void tu_lrz_flush_valid_during_renderpass(struct tu_cmd_buffer *cmd, struct tu_cs *cs) { - if (cmd->state.lrz.disable_for_rp) - return; - /* Even if state is valid, we cannot be sure that secondary * command buffer has the same sticky disable_write_for_rp. */ diff --git a/src/freedreno/vulkan/tu_lrz.h b/src/freedreno/vulkan/tu_lrz.h index ae7b79c9337..414f9a4d401 100644 --- a/src/freedreno/vulkan/tu_lrz.h +++ b/src/freedreno/vulkan/tu_lrz.h @@ -33,11 +33,12 @@ struct tu_lrz_state VkClearValue depth_clear_value; /* If LRZ is in invalid state we cannot use it until depth is cleared */ bool valid : 1; + /* Being invalid at the very start means ew could e.g. skip the clearing. */ + bool valid_at_start: 1; /* Sticky for the RP duration */ bool disable_write_for_rp : 1; - bool disable_for_rp : 1; /* Allows to temporary disable LRZ */ bool enabled : 1; bool fast_clear : 1;