tu: Do not disable LRZ for whole RP if it is disabled in RP
It's not rare when only last few draws in a big renderpass disable LRZ, we shouldn't bail out in such case. If LRZ is disabled in dir tracking bit during binning - LRZ would be disabled for the whole IB in the tiling step, so we should avoid disabling via dir tracking bit and track the state inside the driver. This doesn't work with secondary command buffers (and renderpass resume/suspend), in such cases we have to disable LRZ via dir tracking bit, if LRZ is not valid. Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32868>
This commit is contained in:
committed by
Marge Bot
parent
d6684aedf4
commit
732101d609
@@ -4386,6 +4386,9 @@ tu_CmdExecuteCommands(VkCommandBuffer commandBuffer,
|
||||
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
|
||||
assert(tu_cs_is_empty(&secondary->cs));
|
||||
|
||||
TU_CALLX(cmd->device, tu_lrz_flush_valid_during_renderpass)
|
||||
(cmd, &cmd->draw_cs);
|
||||
|
||||
result = tu_cs_add_entries(&cmd->draw_cs, &secondary->draw_cs);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_command_buffer_set_error(&cmd->vk, result);
|
||||
@@ -7137,8 +7140,14 @@ tu_CmdEndRendering(VkCommandBuffer commandBuffer)
|
||||
{
|
||||
VK_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
if (cmd_buffer->state.suspending)
|
||||
if (cmd_buffer->state.suspending) {
|
||||
cmd_buffer->state.suspended_pass.lrz = cmd_buffer->state.lrz;
|
||||
/* We cannot pass LRZ state to next resuming renderpass, so we have to
|
||||
* force disable it here.
|
||||
*/
|
||||
TU_CALLX(cmd_buffer->device, tu_lrz_flush_valid_during_renderpass)
|
||||
(cmd_buffer, &cmd_buffer->draw_cs);
|
||||
}
|
||||
|
||||
if (!cmd_buffer->state.suspending) {
|
||||
tu_cs_end(&cmd_buffer->draw_cs);
|
||||
|
||||
@@ -353,13 +353,11 @@ tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
return;
|
||||
}
|
||||
|
||||
bool invalidate_lrz = !lrz->valid && lrz->gpu_dir_tracking;
|
||||
if (invalidate_lrz) {
|
||||
/* Following the blob we elect to disable LRZ for the whole renderpass
|
||||
* if it is known that LRZ is disabled somewhere in the renderpass.
|
||||
*
|
||||
if (lrz->disable_for_rp) {
|
||||
/* We may deem necessary to disable LRZ for the whole renderpass.
|
||||
* 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<CHIP>(cmd, cs);
|
||||
tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = 0));
|
||||
@@ -384,7 +382,7 @@ tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
tu_emit_event_write<CHIP>(cmd, cs, FD_LRZ_CLEAR);
|
||||
}
|
||||
|
||||
if (!lrz->fast_clear && !invalidate_lrz) {
|
||||
if (!lrz->fast_clear && !lrz->disable_for_rp) {
|
||||
tu6_clear_lrz<CHIP>(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
|
||||
@@ -414,7 +412,7 @@ tu_lrz_before_tile(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
tu6_emit_lrz_buffer<CHIP>(cs, lrz->image_view->image);
|
||||
|
||||
if (lrz->gpu_dir_tracking) {
|
||||
if (!lrz->valid) {
|
||||
if (lrz->disable_for_rp) {
|
||||
/* Make sure we fail the comparison of depth views */
|
||||
tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(.dword = 0));
|
||||
} else {
|
||||
@@ -448,18 +446,22 @@ tu_lrz_tiling_end(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
tu6_write_lrz_cntl<CHIP>(cmd, cs, {.enable = false});
|
||||
}
|
||||
|
||||
tu_emit_event_write<CHIP>(cmd, cs, FD_LRZ_FLUSH);
|
||||
|
||||
/* If gpu_dir_tracking is enabled and lrz is not valid blob, at this point,
|
||||
* additionally clears direction buffer:
|
||||
* GRAS_LRZ_DEPTH_VIEW(.dword = 0)
|
||||
* GRAS_LRZ_DEPTH_VIEW(.dword = 0xffffffff)
|
||||
* A6XX_GRAS_LRZ_CNTL(.enable = true, .disable_on_wrong_dir = true)
|
||||
* LRZ_CLEAR
|
||||
* LRZ_FLUSH
|
||||
* Since it happens after all of the rendering is done there is no known
|
||||
* reason to do such clear.
|
||||
/* 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 &&
|
||||
!cmd->state.lrz.valid) {
|
||||
tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(
|
||||
.base_layer = 0b11111111111,
|
||||
.layer_count = 0b11111111111,
|
||||
.base_mip_level = 0b1111,
|
||||
));
|
||||
|
||||
tu_emit_event_write<CHIP>(cmd, cs, FD_LRZ_CLEAR);
|
||||
tu_emit_event_write<CHIP>(cmd, cs, FD_LRZ_FLUSH);
|
||||
} else {
|
||||
tu_emit_event_write<CHIP>(cmd, cs, FD_LRZ_FLUSH);
|
||||
}
|
||||
}
|
||||
TU_GENX(tu_lrz_tiling_end);
|
||||
|
||||
@@ -632,17 +634,25 @@ tu_lrz_disable_during_renderpass(struct tu_cmd_buffer *cmd,
|
||||
|
||||
cmd->state.lrz.valid = false;
|
||||
cmd->state.dirty |= TU_CMD_DIRTY_LRZ;
|
||||
|
||||
if (cmd->state.lrz.gpu_dir_tracking) {
|
||||
tu6_write_lrz_cntl<CHIP>(cmd, &cmd->cs, {
|
||||
.enable = true,
|
||||
.dir = LRZ_DIR_INVALID,
|
||||
.disable_on_wrong_dir = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
TU_GENX(tu_lrz_disable_during_renderpass);
|
||||
|
||||
template <chip CHIP>
|
||||
void
|
||||
tu_lrz_flush_valid_during_renderpass(struct tu_cmd_buffer *cmd,
|
||||
struct tu_cs *cs)
|
||||
{
|
||||
if (cmd->state.lrz.valid || cmd->state.lrz.disable_for_rp)
|
||||
return;
|
||||
|
||||
tu6_write_lrz_reg(cmd, cs, A6XX_GRAS_LRZ_DEPTH_VIEW(
|
||||
.base_layer = 0b11111111111,
|
||||
.layer_count = 0b11111111111,
|
||||
.base_mip_level = 0b1111,
|
||||
));
|
||||
}
|
||||
TU_GENX(tu_lrz_flush_valid_during_renderpass);
|
||||
|
||||
/* update lrz state based on stencil-test func:
|
||||
*
|
||||
* Conceptually the order of the pipeline is:
|
||||
@@ -910,17 +920,7 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd,
|
||||
if (disable_lrz)
|
||||
cmd->state.lrz.valid = false;
|
||||
|
||||
if (disable_lrz && cmd->state.lrz.gpu_dir_tracking) {
|
||||
/* Direction byte on GPU should be set to CUR_DIR_DISABLED,
|
||||
* for this it's not enough to emit empty GRAS_LRZ_CNTL.
|
||||
*/
|
||||
gras_lrz_cntl.enable = true;
|
||||
gras_lrz_cntl.dir = LRZ_DIR_INVALID;
|
||||
|
||||
return gras_lrz_cntl;
|
||||
}
|
||||
|
||||
if (temporary_disable_lrz)
|
||||
if (temporary_disable_lrz || disable_lrz)
|
||||
gras_lrz_cntl.enable = false;
|
||||
|
||||
cmd->state.lrz.enabled = cmd->state.lrz.valid && gras_lrz_cntl.enable;
|
||||
|
||||
@@ -33,6 +33,7 @@ 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;
|
||||
bool disable_for_rp : 1;
|
||||
/* Allows to temporary disable LRZ */
|
||||
bool enabled : 1;
|
||||
bool fast_clear : 1;
|
||||
@@ -99,4 +100,9 @@ void
|
||||
tu_lrz_disable_during_renderpass(struct tu_cmd_buffer *cmd,
|
||||
const char *reason);
|
||||
|
||||
template <chip CHIP>
|
||||
void
|
||||
tu_lrz_flush_valid_during_renderpass(struct tu_cmd_buffer *cmd,
|
||||
struct tu_cs *cs);
|
||||
|
||||
#endif /* TU_LRZ_H */
|
||||
|
||||
Reference in New Issue
Block a user