Module: Mesa Branch: master Commit: b2a60c157e4d6cc62c55d8fe8777f7cbd548a722 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b2a60c157e4d6cc62c55d8fe8777f7cbd548a722
Author: Samuel Iglesias Gonsálvez <sigles...@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 <sigles...@igalia.com> Reviewed-by: Eric Anholt <e...@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 _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit