turnip: add LRZ early-z support
Imported the logic from Freedreno driver. Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> Reviewed-by: Eric Anholt <eric@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7186>
This commit is contained in:

committed by
Marge Bot

parent
af049b6668
commit
b2a60c157e
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user