panfrost: Avoid redundant shader executions with mask=0x0
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 21 May 2020 19:49:30 +0000 (15:49 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 21 May 2020 19:49:47 +0000 (15:49 -0400)
Only works for a few Midgard GPUs, but hey.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5124>

src/gallium/drivers/panfrost/pan_assemble.c
src/gallium/drivers/panfrost/pan_cmdstream.c
src/gallium/drivers/panfrost/pan_context.h
src/panfrost/include/panfrost-quirks.h

index 53bf9caaafca9876be0d921a286cfe10f19175ce..f804e2beb13f2da78570fb3fe4dd22c9260dcd44 100644 (file)
@@ -196,6 +196,14 @@ panfrost_shader_compile(struct panfrost_context *ctx,
                         state->writes_depth = true;
                 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
                         state->writes_stencil = true;
+
+                /* List of reasons we need to execute frag shaders when things
+                 * are masked off */
+
+                state->fs_sidefx =
+                        s->info.writes_memory ||
+                        s->info.fs.uses_discard ||
+                        s->info.fs.uses_demote;
                 break;
         case MESA_SHADER_COMPUTE:
                 /* TODO: images */
index caf01663a488cf34d63d9598cb483ebd6a2b63fe..59a1799bc86810b4dac1f4085f463c1c68797e07 100644 (file)
@@ -620,6 +620,27 @@ panfrost_frag_meta_zsa_update(struct panfrost_context *ctx,
         fragmeta->unknown2_3 |= MALI_DEPTH_FUNC(panfrost_translate_compare_func(zfunc));
 }
 
+static bool
+panfrost_fs_required(
+                struct panfrost_shader_state *fs,
+                struct panfrost_blend_final *blend,
+                unsigned rt_count)
+{
+        /* If we generally have side effects */
+        if (fs->fs_sidefx)
+                return true;
+
+        /* If colour is written we need to execute */
+        for (unsigned i = 0; i < rt_count; ++i) {
+                if (!blend[i].no_colour)
+                        return true;
+        }
+
+        /* If depth is written and not implied we need to execute.
+         * TODO: Predicate on Z/S writes being enabled */
+        return (fs->writes_depth || fs->writes_stencil);
+}
+
 static void
 panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
                                 struct mali_shader_meta *fragmeta,
@@ -642,6 +663,21 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
                 blend[c] = panfrost_get_blend_for_context(ctx, c, &shader_bo,
                                                           &shader_offset);
 
+        /* Disable shader execution if we can */
+        if (dev->quirks & MIDGARD_SHADERLESS
+                        && !panfrost_fs_required(fs, blend, rt_count)) {
+                fragmeta->shader = 0;
+                fragmeta->attribute_count = 0;
+                fragmeta->varying_count = 0;
+                fragmeta->texture_count = 0;
+                fragmeta->sampler_count = 0;
+
+                /* This feature is not known to work on Bifrost */
+                fragmeta->midgard1.work_count = 1;
+                fragmeta->midgard1.uniform_count = 0;
+                fragmeta->midgard1.uniform_buffer_count = 0;
+        }
+
          /* If there is a blend shader, work registers are shared. We impose 8
           * work registers as a limit for blend shaders. Should be lower XXX */
 
index c0a6d5fa1d6b8f140fb3fcdcf5d8d6067e2c568a..a4ea44a96b9b235506fee7007fd2da3a6a98749c 100644 (file)
@@ -195,6 +195,10 @@ struct panfrost_shader_state {
         unsigned stack_size;
         unsigned shared_size;
 
+        /* Does the fragment shader have side effects? In particular, if output
+         * is masked out, is it legal to skip shader execution? */
+        bool fs_sidefx;
+
         /* For Bifrost - output type for each RT */
         enum bifrost_shader_type blend_types[BIFROST_MAX_RENDER_TARGET_COUNT];
 
index e45191fe11aaf8872687ba900701280401489107..1d2ca775e45a300b240acf00cfd79bae144fe6fe 100644 (file)
 /* What it says on the tin */
 #define HAS_SWIZZLES (1 << 4)
 
+/* Support for setting shader to NULL for masking out colour (while allowing
+ * Z/S updates to proceed) */
+
+#define MIDGARD_SHADERLESS (1 << 5)
+
 /* Quirk collections common to particular uarchs */
 
 #define MIDGARD_QUIRKS (MIDGARD_BROKEN_FP16 | HAS_SWIZZLES)
@@ -74,7 +79,7 @@ panfrost_get_quirks(unsigned gpu_id)
         case 0x750:
         case 0x860:
         case 0x880:
-                return MIDGARD_QUIRKS;
+                return MIDGARD_QUIRKS | MIDGARD_SHADERLESS;
 
         case 0x6000: /* G71 */
                 return BIFROST_QUIRKS | HAS_SWIZZLES;