diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index 795634d0670..7d546c5c4a8 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -4960,6 +4960,12 @@ tu_CmdExecuteCommands(VkCommandBuffer commandBuffer, */ if (!secondary->state.lrz.valid) cmd->state.lrz.valid = false; + if (secondary->state.lrz.gpu_dir_set) + cmd->state.lrz.gpu_dir_set = true; + if (cmd->state.lrz.prev_direction == TU_LRZ_UNKNOWN && + secondary->state.lrz.prev_direction != TU_LRZ_UNKNOWN) + cmd->state.lrz.prev_direction = + secondary->state.lrz.prev_direction; tu_clone_trace(cmd, &cmd->draw_cs, &secondary->trace); tu_render_pass_state_merge(&cmd->state.rp, &secondary->state.rp); diff --git a/src/freedreno/vulkan/tu_lrz.cc b/src/freedreno/vulkan/tu_lrz.cc index 705a91d60a5..64697979052 100644 --- a/src/freedreno/vulkan/tu_lrz.cc +++ b/src/freedreno/vulkan/tu_lrz.cc @@ -504,8 +504,18 @@ 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.valid_at_start && - !cmd->state.lrz.valid) { + bool disable_for_next_rp = cmd->state.lrz.valid_at_start && + !cmd->state.lrz.valid; + /* If the render pass writes depth (with direction) but doesn't set + * direction on the GPU, the LRZ buffer cannot be used in subsequent + * render passes because the direction information is lost. + */ + if (!cmd->state.lrz.gpu_dir_set && + cmd->state.lrz.prev_direction != TU_LRZ_UNKNOWN) { + disable_for_next_rp = true; + } + + if (cmd->state.lrz.gpu_dir_tracking && disable_for_next_rp) { tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW( .base_layer = 0b11111111111, .layer_count = 0b11111111111, @@ -962,6 +972,11 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd, if (!cmd->state.lrz.enabled) memset(&gras_lrz_cntl, 0, sizeof(gras_lrz_cntl)); + if (cmd->state.lrz.enabled && gras_lrz_cntl.lrz_write && + cmd->state.lrz.prev_direction != TU_LRZ_UNKNOWN) { + cmd->state.lrz.gpu_dir_set = true; + } + return gras_lrz_cntl; } diff --git a/src/freedreno/vulkan/tu_lrz.h b/src/freedreno/vulkan/tu_lrz.h index 414f9a4d401..1ff80e0874d 100644 --- a/src/freedreno/vulkan/tu_lrz.h +++ b/src/freedreno/vulkan/tu_lrz.h @@ -45,6 +45,7 @@ struct tu_lrz_state bool gpu_dir_tracking : 1; /* Continue using old LRZ state (LOAD_OP_LOAD of depth) */ bool reuse_previous_state : 1; + bool gpu_dir_set : 1; enum tu_lrz_direction prev_direction; };