Mesa (main): panfrost: Use early-ZS helpers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 13 21:19:31 UTC 2022


Module: Mesa
Branch: main
Commit: 3a0a8688d3a8668a82cb25f0178f1eae3799a9f8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a0a8688d3a8668a82cb25f0178f1eae3799a9f8

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Fri Jul  8 13:46:49 2022 -0400

panfrost: Use early-ZS helpers

Remove the previous compile-time early-ZS implementation and replace it with the
decoupled early-ZS implementation. This uses more efficient settings in some
cases (depth/stencil tests always passes or do not write), and fixes the
settings used in another case (alpha-to-coverage enabled with an otherwise
early-ZS shader.)

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Closes: #6206
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17428>

---

 src/gallium/drivers/panfrost/pan_cmdstream.c | 30 +++++++++++++---
 src/gallium/drivers/panfrost/pan_context.c   |  2 ++
 src/gallium/drivers/panfrost/pan_context.h   |  3 ++
 src/panfrost/lib/pan_blitter.c               | 10 ++++--
 src/panfrost/lib/pan_shader.h                | 53 ----------------------------
 src/panfrost/vulkan/panvk_vX_cs.c            | 12 +++++++
 6 files changed, 51 insertions(+), 59 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index ce5d9ac93e1..7e4ec15fcbe 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -70,6 +70,9 @@ struct panfrost_zsa_state {
          */
         bool zs_always_passes;
 
+        /* Are depth or stencil writes possible? */
+        bool writes_zs;
+
 #if PAN_ARCH <= 7
         /* Prepacked words from the RSD */
         struct mali_multisample_misc_packed rsd_depth;
@@ -526,9 +529,21 @@ panfrost_prepare_fs_state(struct panfrost_context *ctx,
         for (unsigned c = 0; c < rt_count; ++c)
                 has_blend_shader |= (blend_shaders[c] != 0);
 
+        bool has_oq = ctx->occlusion_query && ctx->active_queries;
+
         pan_pack(rsd, RENDERER_STATE, cfg) {
                 if (panfrost_fs_required(fs, so, &ctx->pipe_framebuffer, zsa)) {
 #if PAN_ARCH >= 6
+                        struct pan_earlyzs_state earlyzs =
+                               pan_earlyzs_get(fs->earlyzs,
+                                               ctx->depth_stencil->writes_zs ||
+                                               has_oq,
+                                               ctx->blend->base.alpha_to_coverage,
+                                               ctx->depth_stencil->zs_always_passes);
+
+                        cfg.properties.pixel_kill_operation = earlyzs.kill;
+                        cfg.properties.zs_update_operation = earlyzs.update;
+
                         cfg.properties.allow_forward_pixel_to_kill =
                                 pan_allow_forward_pixel_to_kill(ctx, fs);
 #else
@@ -544,7 +559,6 @@ panfrost_prepare_fs_state(struct panfrost_context *ctx,
 
                         /* Hardware quirks around early-zs forcing without a
                          * depth buffer. Note this breaks occlusion queries. */
-                        bool has_oq = ctx->occlusion_query && ctx->active_queries;
                         bool force_ez_with_discard = !zsa->enabled && !has_oq;
 
                         cfg.properties.shader_reads_tilebuffer =
@@ -3326,9 +3340,16 @@ panfrost_emit_draw(void *out,
                 cfg.depth_stencil = batch->depth_stencil;
 
                 if (fs_required) {
-                        struct pan_pixel_kill kill = pan_shader_classify_pixel_kill_coverage(&fs->info);
-                        cfg.pixel_kill_operation = kill.pixel_kill;
-                        cfg.zs_update_operation = kill.zs_update;
+                        bool has_oq = ctx->occlusion_query && ctx->active_queries;
+
+                        struct pan_earlyzs_state earlyzs =
+                               pan_earlyzs_get(fs->earlyzs,
+                                               ctx->depth_stencil->writes_zs || has_oq,
+                                               ctx->blend->base.alpha_to_coverage,
+                                               ctx->depth_stencil->zs_always_passes);
+
+                        cfg.pixel_kill_operation = earlyzs.kill;
+                        cfg.zs_update_operation = earlyzs.update;
 
                         cfg.allow_forward_pixel_to_kill = pan_allow_forward_pixel_to_kill(ctx, fs);
                         cfg.allow_forward_pixel_to_be_killed = !fs->info.writes_global;
@@ -4449,6 +4470,7 @@ panfrost_create_depth_stencil_state(struct pipe_context *pipe,
                 (zsa->depth_enabled && zsa->depth_func != PIPE_FUNC_ALWAYS);
 
         so->zs_always_passes = pipe_zs_always_passes(zsa);
+        so->writes_zs = util_writes_depth_stencil(zsa);
 
         /* TODO: Bounds test should be easy */
         assert(!zsa->depth_bounds_test);
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index d17455aa908..25c053f57b2 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -510,6 +510,8 @@ panfrost_new_variant_locked(
                 update_so_info(&shader_state->stream_output,
                                shader_state->info.outputs_written);
 
+        shader_state->earlyzs = pan_earlyzs_analyze(&shader_state->info);
+
         return variant;
 }
 
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 77933d7a4a4..870258e3594 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -33,6 +33,7 @@
 #include "pan_blend_cso.h"
 #include "pan_encoder.h"
 #include "pan_texture.h"
+#include "pan_earlyzs.h"
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_config.h"
@@ -290,6 +291,8 @@ struct panfrost_shader_state {
 
         struct pan_shader_info info;
 
+        struct pan_earlyzs_lut earlyzs;
+
         /* Attached transform feedback program, if one exists */
         struct panfrost_shader_state *xfb;
 
diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c
index 287969521f4..03b5cba95b1 100644
--- a/src/panfrost/lib/pan_blitter.c
+++ b/src/panfrost/lib/pan_blitter.c
@@ -259,8 +259,14 @@ pan_blitter_emit_rsd(const struct panfrost_device *dev,
                 cfg.stencil_back = cfg.stencil_front;
 
 #if PAN_ARCH >= 6
-                /* Skipping ATEST requires forcing Z/S */
-                if (!zs) {
+                if (zs) {
+                        /* Writing Z/S requires late updates */
+                        cfg.properties.zs_update_operation =
+                                MALI_PIXEL_KILL_FORCE_LATE;
+                        cfg.properties.pixel_kill_operation =
+                                MALI_PIXEL_KILL_FORCE_LATE;
+                } else {
+                        /* Skipping ATEST requires forcing Z/S */
                         cfg.properties.zs_update_operation =
                                 MALI_PIXEL_KILL_STRONG_EARLY;
                         cfg.properties.pixel_kill_operation =
diff --git a/src/panfrost/lib/pan_shader.h b/src/panfrost/lib/pan_shader.h
index 11770e74cad..dce72e5cba0 100644
--- a/src/panfrost/lib/pan_shader.h
+++ b/src/panfrost/lib/pan_shader.h
@@ -68,54 +68,6 @@ pan_register_allocation(unsigned work_reg_count)
 }
 #endif
 
-#if PAN_ARCH >= 6
-/* Classify a shader into the following pixel kill categories:
- *
- * (force early, strong early): no side effects/depth/stencil/coverage writes (force)
- * (weak early, weak early): no side effects/depth/stencil/coverage writes
- * (weak early, force late): no side effects/depth/stencil writes
- * (force late, weak early): side effects but no depth/stencil/coverage writes
- * (force late, force early): only run for side effects
- * (force late, force late): depth/stencil writes
- *
- * Note that discard is considered a coverage write. TODO: what about
- * alpha-to-coverage?
- * */
-
-struct pan_pixel_kill {
-        enum mali_pixel_kill pixel_kill;
-        enum mali_pixel_kill zs_update;
-};
-
-#define RETURN_PIXEL_KILL(kill, update) return (struct pan_pixel_kill) { \
-        MALI_PIXEL_KILL_## kill, MALI_PIXEL_KILL_## update \
-}
-
-static inline struct pan_pixel_kill
-pan_shader_classify_pixel_kill_coverage(const struct pan_shader_info *info)
-{
-        bool force_early = info->fs.early_fragment_tests;
-        bool sidefx = info->writes_global;
-        bool coverage = info->fs.writes_coverage || info->fs.can_discard;
-        bool depth = info->fs.writes_depth;
-        bool stencil = info->fs.writes_stencil;
-
-        if (force_early)
-                RETURN_PIXEL_KILL(FORCE_EARLY, STRONG_EARLY);
-        else if (depth || stencil || (sidefx && coverage))
-                RETURN_PIXEL_KILL(FORCE_LATE, FORCE_LATE);
-        else if (sidefx)
-                RETURN_PIXEL_KILL(FORCE_LATE, WEAK_EARLY);
-        else if (coverage)
-                RETURN_PIXEL_KILL(WEAK_EARLY, FORCE_LATE);
-        else
-                RETURN_PIXEL_KILL(WEAK_EARLY, WEAK_EARLY);
-}
-
-#undef RETURN_PIXEL_KILL
-
-#endif
-
 static inline enum mali_depth_source
 pan_depth_source(const struct pan_shader_info *info)
 {
@@ -229,11 +181,6 @@ pan_shader_prepare_bifrost_rsd(const struct pan_shader_info *info,
         pan_make_preload(info->stage, info->preload, &rsd->preload);
 
         if (info->stage == MESA_SHADER_FRAGMENT) {
-                struct pan_pixel_kill kill = pan_shader_classify_pixel_kill_coverage(info);
-
-                rsd->properties.pixel_kill_operation = kill.pixel_kill;
-                rsd->properties.zs_update_operation = kill.zs_update;
-
                 rsd->properties.shader_modifies_coverage =
                         info->fs.writes_coverage || info->fs.can_discard;
 
diff --git a/src/panfrost/vulkan/panvk_vX_cs.c b/src/panfrost/vulkan/panvk_vX_cs.c
index 15068f68073..f10feaf2731 100644
--- a/src/panfrost/vulkan/panvk_vX_cs.c
+++ b/src/panfrost/vulkan/panvk_vX_cs.c
@@ -32,6 +32,7 @@
 #include "pan_encoder.h"
 #include "pan_pool.h"
 #include "pan_shader.h"
+#include "pan_earlyzs.h"
 
 #include "panvk_cs.h"
 #include "panvk_private.h"
@@ -722,6 +723,17 @@ panvk_per_arch(emit_base_fs_rsd)(const struct panvk_device *dev,
                  !(rt_mask & ~rt_written) &&
                  !pipeline->ms.alpha_to_coverage &&
                  !pipeline->blend.reads_dest;
+
+         bool writes_zs = pipeline->zs.z_write || pipeline->zs.s_test;
+         bool zs_always_passes = !pipeline->zs.z_test && !pipeline->zs.s_test;
+         bool oq = false; /* TODO: Occlusion queries */
+
+         struct pan_earlyzs_state earlyzs =
+            pan_earlyzs_get(pan_earlyzs_analyze(info), writes_zs || oq,
+                            pipeline->ms.alpha_to_coverage, zs_always_passes);
+
+         cfg.properties.pixel_kill_operation = earlyzs.kill;
+         cfg.properties.zs_update_operation = earlyzs.update;
       } else {
          cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
          cfg.properties.allow_forward_pixel_to_kill = true;



More information about the mesa-commit mailing list