turnip: enable LRZ
v2:
* Use sub_cs when creating the IB in tu6_build_lrz(). (Jonathan Marek)
* Emit tu6_build_lrz() only when pipeline state changes or there is a
clear. (Jonathan Marek)
v3:
* Don't modify tu_pipeline object, track the changes in command buffer
state.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5146>
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index b2e9307..c128bc1 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -3185,6 +3185,48 @@
return VK_SUCCESS;
}
+static struct tu_draw_state
+tu6_build_lrz(struct tu_cmd_buffer *cmd)
+{
+ const uint32_t a = cmd->state.subpass->depth_stencil_attachment.attachment;
+ struct tu_cs lrz_cs;
+ struct tu_draw_state ds = tu_cs_draw_state(&cmd->sub_cs, &lrz_cs, 4);
+
+ if (cmd->state.pipeline->lrz.invalidate) {
+ /* LRZ is not valid for next draw commands, so don't use it until cleared */
+ cmd->state.lrz.valid = false;
+ }
+
+ if (a == VK_ATTACHMENT_UNUSED || !cmd->state.lrz.valid) {
+ tu_cs_emit_regs(&lrz_cs, A6XX_GRAS_LRZ_CNTL(0));
+ tu_cs_emit_regs(&lrz_cs, A6XX_RB_LRZ_CNTL(0));
+ return ds;
+ }
+
+ /* Disable LRZ writes when blend is enabled, since the
+ * resulting pixel value from the blend-draw
+ * depends on an earlier draw, which LRZ in the draw pass
+ * could early-reject if the previous blend-enabled draw wrote LRZ.
+ *
+ * TODO: We need to disable LRZ writes only for the binning pass.
+ * Therefore, we need to emit it in a separate draw state. We keep
+ * it disabled for sysmem path as well for the moment.
+ */
+ bool lrz_write = cmd->state.pipeline->lrz.write;
+ if (cmd->state.pipeline->lrz.blend_disable_write)
+ lrz_write = false;
+
+ tu_cs_emit_regs(&lrz_cs, A6XX_GRAS_LRZ_CNTL(
+ .enable = cmd->state.pipeline->lrz.enable,
+ .greater = cmd->state.pipeline->lrz.greater,
+ .lrz_write = lrz_write,
+ .z_test_enable = cmd->state.pipeline->lrz.z_test_enable,
+ ));
+
+ tu_cs_emit_regs(&lrz_cs, A6XX_RB_LRZ_CNTL(.enable = cmd->state.pipeline->lrz.enable));
+ return ds;
+}
+
static VkResult
tu6_draw_common(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
@@ -3200,7 +3242,8 @@
tu_emit_cache_flush_renderpass(cmd, cs);
- /* TODO lrz */
+ if (cmd->state.dirty & TU_CMD_DIRTY_LRZ)
+ cmd->state.lrz.state = tu6_build_lrz(cmd);
tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0(
.primitive_restart =
@@ -3298,6 +3341,8 @@
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DESC_SETS_LOAD, pipeline->load_state);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VB, cmd->state.vertex_buffers);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params);
+ if (cmd->state.dirty & TU_CMD_DIRTY_LRZ)
+ tu_cs_emit_draw_state(cs, TU_DRAW_STATE_LRZ, cmd->state.lrz.state);
for (uint32_t i = 0; i < ARRAY_SIZE(cmd->state.dynamic_state); i++) {
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i,
@@ -3315,6 +3360,7 @@
((cmd->state.dirty & TU_CMD_DIRTY_SHADER_CONSTS) ? 5 : 0) +
((cmd->state.dirty & TU_CMD_DIRTY_DESC_SETS_LOAD) ? 1 : 0) +
((cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) ? 1 : 0) +
+ ((cmd->state.dirty & TU_CMD_DIRTY_LRZ) ? 1 : 0) +
1; /* vs_params */
if ((cmd->state.dirty & TU_CMD_DIRTY_VB_STRIDE) &&
@@ -3345,6 +3391,9 @@
cmd->state.dynamic_state[TU_DYNAMIC_STATE_VB_STRIDE]);
}
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params);
+
+ if (cmd->state.dirty & TU_CMD_DIRTY_LRZ)
+ tu_cs_emit_draw_state(cs, TU_DRAW_STATE_LRZ, cmd->state.lrz.state);
}
tu_cs_sanity_check(cs);
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 9e53f13..338eb47 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -490,6 +490,7 @@
TU_DRAW_STATE_VS_PARAMS,
TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM,
TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM,
+ TU_DRAW_STATE_LRZ,
/* dynamic state related draw states */
TU_DRAW_STATE_DYNAMIC,
@@ -852,6 +853,7 @@
/* Depth/Stencil image currently on use to do LRZ */
struct tu_image *image;
bool valid : 1;
+ struct tu_draw_state state;
};
struct tu_cmd_state