Commit b2a60c15 authored by Samuel Iglesias Gonsálvez's avatar Samuel Iglesias Gonsálvez Committed by Marge Bot
Browse files

turnip: add LRZ early-z support



Imported the logic from Freedreno driver.
Signed-off-by: Samuel Iglesias Gonsálvez's avatarSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Emma Anholt's avatarEric Anholt <eric@anholt.net>
Part-of: <mesa/mesa!7186>
parent af049b66
Pipeline #304751 waiting for manual action with stages
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment