Mesa (master): turnip: add LRZ early-z support
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Apr 20 10:23:46 UTC 2021
Module: Mesa
Branch: master
Commit: b2a60c157e4d6cc62c55d8fe8777f7cbd548a722
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b2a60c157e4d6cc62c55d8fe8777f7cbd548a722
Author: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
Date: Thu Feb 4 16:50:12 2021 +0100
turnip: add LRZ early-z support
Imported the logic from Freedreno driver.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7186>
---
src/freedreno/vulkan/tu_cmd_buffer.c | 96 ++++++++++++++++++++++++++++++++++--
src/freedreno/vulkan/tu_pipeline.c | 34 ++++++-------
src/freedreno/vulkan/tu_private.h | 5 ++
3 files changed, 114 insertions(+), 21 deletions(-)
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 85182464a11..1841fd3b80d 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -3517,6 +3517,91 @@ tu6_build_lrz(struct tu_cmd_buffer *cmd)
return ds;
}
+static bool
+tu6_writes_depth(struct tu_cmd_buffer *cmd, bool depth_test_enable)
+{
+ bool depth_write_enable =
+ cmd->state.rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
+
+ VkCompareOp depth_compare_op =
+ (cmd->state.rb_depth_cntl & A6XX_RB_DEPTH_CNTL_ZFUNC__MASK) >> A6XX_RB_DEPTH_CNTL_ZFUNC__SHIFT;
+
+ bool depth_compare_op_writes = depth_compare_op != VK_COMPARE_OP_NEVER;
+
+ return depth_test_enable && depth_write_enable && depth_compare_op_writes;
+}
+
+static bool
+tu6_writes_stencil(struct tu_cmd_buffer *cmd)
+{
+ bool stencil_test_enable =
+ cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE;
+
+ bool stencil_front_writemask =
+ (cmd->state.pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
+ (cmd->state.dynamic_stencil_wrmask & 0xff) :
+ (cmd->state.pipeline->stencil_wrmask & 0xff);
+
+ bool stencil_back_writemask =
+ (cmd->state.pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
+ ((cmd->state.dynamic_stencil_wrmask & 0xff00) >> 8) :
+ (cmd->state.pipeline->stencil_wrmask & 0xff00) >> 8;
+
+ VkStencilOp front_fail_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_FAIL__MASK) >> A6XX_RB_STENCIL_CONTROL_FAIL__SHIFT;
+ VkStencilOp front_pass_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_ZPASS__MASK) >> A6XX_RB_STENCIL_CONTROL_ZPASS__SHIFT;
+ VkStencilOp front_depth_fail_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_ZFAIL__MASK) >> A6XX_RB_STENCIL_CONTROL_ZFAIL__SHIFT;
+ VkStencilOp back_fail_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_FAIL_BF__MASK) >> A6XX_RB_STENCIL_CONTROL_FAIL_BF__SHIFT;
+ VkStencilOp back_pass_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK) >> A6XX_RB_STENCIL_CONTROL_ZPASS_BF__SHIFT;
+ VkStencilOp back_depth_fail_op =
+ (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK) >> A6XX_RB_STENCIL_CONTROL_ZFAIL_BF__SHIFT;
+
+ bool stencil_front_op_writes =
+ front_pass_op != VK_STENCIL_OP_KEEP &&
+ front_fail_op != VK_STENCIL_OP_KEEP &&
+ front_depth_fail_op != VK_STENCIL_OP_KEEP;
+
+ bool stencil_back_op_writes =
+ back_pass_op != VK_STENCIL_OP_KEEP &&
+ back_fail_op != VK_STENCIL_OP_KEEP &&
+ back_depth_fail_op != VK_STENCIL_OP_KEEP;
+
+ return stencil_test_enable &&
+ ((stencil_front_writemask && stencil_front_op_writes) ||
+ (stencil_back_writemask && stencil_back_op_writes));
+}
+
+static struct tu_draw_state
+tu6_build_depth_plane_z_mode(struct tu_cmd_buffer *cmd)
+{
+ struct tu_cs cs;
+ struct tu_draw_state ds = tu_cs_draw_state(&cmd->sub_cs, &cs, 4);
+
+ enum a6xx_ztest_mode zmode = A6XX_EARLY_Z;
+ bool depth_test_enable = cmd->state.rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_ENABLE;
+ bool depth_write = tu6_writes_depth(cmd, depth_test_enable);
+ bool stencil_write = tu6_writes_stencil(cmd);
+
+ if (cmd->state.pipeline->lrz.fs_has_kill &&
+ (depth_write || stencil_write)) {
+ zmode = cmd->state.lrz.valid ? A6XX_EARLY_LRZ_LATE_Z : A6XX_LATE_Z;
+ }
+
+ if (cmd->state.pipeline->lrz.force_late_z || !depth_test_enable)
+ zmode = A6XX_LATE_Z;
+
+ tu_cs_emit_pkt4(&cs, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1);
+ tu_cs_emit(&cs, A6XX_GRAS_SU_DEPTH_PLANE_CNTL_Z_MODE(zmode));
+
+ tu_cs_emit_pkt4(&cs, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1);
+ tu_cs_emit(&cs, A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(zmode));
+ return ds;
+}
+
static VkResult
tu6_draw_common(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
@@ -3533,8 +3618,10 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
tu_emit_cache_flush_renderpass(cmd, cs);
- if (dirty_lrz)
+ if (dirty_lrz) {
cmd->state.lrz.state = tu6_build_lrz(cmd);
+ cmd->state.depth_plane_state = tu6_build_depth_plane_z_mode(cmd);
+ }
tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0(
.primitive_restart =
@@ -3623,6 +3710,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
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);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_LRZ, cmd->state.lrz.state);
+ tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DEPTH_PLANE, cmd->state.depth_plane_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,
@@ -3640,7 +3728,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
((cmd->state.dirty & TU_CMD_DIRTY_SHADER_CONSTS) ? 2 : 0) +
((cmd->state.dirty & TU_CMD_DIRTY_DESC_SETS_LOAD) ? 1 : 0) +
((cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) ? 1 : 0) +
- (dirty_lrz ? 1 : 0) +
+ (dirty_lrz ? 2 : 0) +
1; /* vs_params */
if ((cmd->state.dirty & TU_CMD_DIRTY_VB_STRIDE) &&
@@ -3669,8 +3757,10 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
}
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params);
- if (dirty_lrz)
+ if (dirty_lrz) {
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_LRZ, cmd->state.lrz.state);
+ tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DEPTH_PLANE, cmd->state.depth_plane_state);
+ }
}
tu_cs_sanity_check(cs);
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 2c4a9521f45..e866f8d7e00 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -1371,7 +1371,8 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
const struct ir3_shader_variant *fs,
uint32_t mrt_count, bool dual_src_blend,
uint32_t render_components,
- bool no_earlyz)
+ bool no_earlyz,
+ struct tu_pipeline *pipeline)
{
uint32_t smask_regid, posz_regid, stencilref_regid;
@@ -1417,20 +1418,14 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
tu_cs_emit_regs(cs,
A6XX_RB_RENDER_COMPONENTS(.dword = render_components));
- enum a6xx_ztest_mode zmode;
+ if (pipeline) {
+ pipeline->lrz.fs_has_kill = fs->has_kill;
- if ((fs->shader && !fs->shader->nir->info.fs.early_fragment_tests) &&
- (fs->no_earlyz || fs->has_kill || fs->writes_pos || fs->writes_stencilref || no_earlyz || fs->writes_smask)) {
- zmode = A6XX_LATE_Z;
- } else {
- zmode = A6XX_EARLY_Z;
+ if ((fs->shader && !fs->shader->nir->info.fs.early_fragment_tests) &&
+ (fs->no_earlyz || fs->has_kill || fs->writes_pos || fs->writes_stencilref || no_earlyz || fs->writes_smask)) {
+ pipeline->lrz.force_late_z = true;
+ }
}
-
- tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1);
- tu_cs_emit(cs, A6XX_GRAS_SU_DEPTH_PLANE_CNTL_Z_MODE(zmode));
-
- tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1);
- tu_cs_emit(cs, A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(zmode));
}
static void
@@ -1498,7 +1493,8 @@ tu6_emit_geom_tess_consts(struct tu_cs *cs,
static void
tu6_emit_program(struct tu_cs *cs,
struct tu_pipeline_builder *builder,
- bool binning_pass)
+ bool binning_pass,
+ struct tu_pipeline *pipeline)
{
const struct ir3_shader_variant *vs = builder->variants[MESA_SHADER_VERTEX];
const struct ir3_shader_variant *bs = builder->binning_variant;
@@ -1592,7 +1588,8 @@ tu6_emit_program(struct tu_cs *cs,
tu6_emit_fs_outputs(cs, fs, mrt_count,
builder->use_dual_src_blend,
render_components,
- no_earlyz);
+ no_earlyz,
+ pipeline);
} else {
/* TODO: check if these can be skipped if fs is disabled */
struct ir3_shader_variant dummy_variant = {};
@@ -1600,7 +1597,8 @@ tu6_emit_program(struct tu_cs *cs,
tu6_emit_fs_outputs(cs, &dummy_variant, mrt_count,
builder->use_dual_src_blend,
render_components,
- no_earlyz);
+ no_earlyz,
+ NULL);
}
if (gs || hs) {
@@ -2421,11 +2419,11 @@ tu_pipeline_builder_parse_shader_stages(struct tu_pipeline_builder *builder,
{
struct tu_cs prog_cs;
tu_cs_begin_sub_stream(&pipeline->cs, 512, &prog_cs);
- tu6_emit_program(&prog_cs, builder, false);
+ tu6_emit_program(&prog_cs, builder, false, pipeline);
pipeline->program.state = tu_cs_end_draw_state(&pipeline->cs, &prog_cs);
tu_cs_begin_sub_stream(&pipeline->cs, 512, &prog_cs);
- tu6_emit_program(&prog_cs, builder, true);
+ tu6_emit_program(&prog_cs, builder, true, pipeline);
pipeline->program.binning_state = tu_cs_end_draw_state(&pipeline->cs, &prog_cs);
VkShaderStageFlags stages = 0;
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index d2a46ec9861..99e2f1f63e2 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -487,6 +487,7 @@ enum tu_draw_state_group_id
TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM,
TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM,
TU_DRAW_STATE_LRZ,
+ TU_DRAW_STATE_DEPTH_PLANE,
/* dynamic state related draw states */
TU_DRAW_STATE_DYNAMIC,
@@ -849,6 +850,8 @@ enum tu_lrz_direction {
struct tu_lrz_pipeline
{
uint32_t force_disable_mask;
+ bool fs_has_kill;
+ bool force_late_z;
};
struct tu_lrz_state
@@ -931,6 +934,8 @@ struct tu_cmd_state
bool predication_active;
struct tu_lrz_state lrz;
+
+ struct tu_draw_state depth_plane_state;
};
struct tu_cmd_pool
More information about the mesa-commit
mailing list