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

Author: Boris Brezillon <[email protected]>
Date:   Mon Sep  6 14:16:58 2021 +0200

pan/lower_fb: Re-order components when dealing with raw formats

The output swizzle defined in the render-target descriptor is ignored
when the format is RAW. In that case, we have to swap the components
when lowering FB stores/loads if we want to get the right color.

Signed-off-by: Boris Brezillon <[email protected]>
Acked-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12793>

---

 src/gallium/drivers/panfrost/pan_screen.h |  2 +-
 src/panfrost/lib/pan_shader.c             | 11 ++++++-
 src/panfrost/lib/pan_shader.h             |  2 +-
 src/panfrost/midgard/midgard_compile.c    |  3 +-
 src/panfrost/util/pan_ir.h                |  1 +
 src/panfrost/util/pan_lower_framebuffer.c | 48 +++++++++++++++++++++++++++++--
 src/panfrost/util/pan_lower_framebuffer.h |  4 ++-
 7 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_screen.h 
b/src/gallium/drivers/panfrost/pan_screen.h
index c7ab028c554..6f2676fe9ff 100644
--- a/src/gallium/drivers/panfrost/pan_screen.h
+++ b/src/gallium/drivers/panfrost/pan_screen.h
@@ -90,7 +90,7 @@ struct panfrost_vtable {
         /* Shader compilation methods */
         const nir_shader_compiler_options *(*get_compiler_options)(void);
         void (*compile_shader)(nir_shader *s,
-                               const struct panfrost_compile_inputs *inputs,
+                               struct panfrost_compile_inputs *inputs,
                                struct util_dynarray *binary,
                                struct pan_shader_info *info);
 };
diff --git a/src/panfrost/lib/pan_shader.c b/src/panfrost/lib/pan_shader.c
index 8f7d43ecc5f..aac31457b42 100644
--- a/src/panfrost/lib/pan_shader.c
+++ b/src/panfrost/lib/pan_shader.c
@@ -24,6 +24,7 @@
 
 #include "pan_device.h"
 #include "pan_shader.h"
+#include "pan_format.h"
 
 #if PAN_ARCH <= 5
 #include "panfrost/midgard/midgard_compile.h"
@@ -177,7 +178,7 @@ bifrost_blend_type_from_nir(nir_alu_type nir_type)
 
 void
 GENX(pan_shader_compile)(nir_shader *s,
-                         const struct panfrost_compile_inputs *inputs,
+                         struct panfrost_compile_inputs *inputs,
                          struct util_dynarray *binary,
                          struct pan_shader_info *info)
 {
@@ -186,6 +187,14 @@ GENX(pan_shader_compile)(nir_shader *s,
 #if PAN_ARCH >= 6
         bifrost_compile_shader_nir(s, inputs, binary, info);
 #else
+        for (unsigned i = 0; i < ARRAY_SIZE(inputs->rt_formats); i++) {
+                enum pipe_format fmt = inputs->rt_formats[i];
+                unsigned wb_fmt = panfrost_blendable_formats_v6[fmt].writeback;
+
+                if (wb_fmt <= MALI_MFBD_COLOR_FORMAT_RAW2048)
+                        inputs->raw_fmt_mask |= BITFIELD_BIT(i);
+        }
+
         midgard_compile_shader_nir(s, inputs, binary, info);
 #endif
 
diff --git a/src/panfrost/lib/pan_shader.h b/src/panfrost/lib/pan_shader.h
index fbf88b972f7..616155ca368 100644
--- a/src/panfrost/lib/pan_shader.h
+++ b/src/panfrost/lib/pan_shader.h
@@ -39,7 +39,7 @@ GENX(pan_shader_get_compiler_options)(void);
 
 void
 GENX(pan_shader_compile)(nir_shader *nir,
-                         const struct panfrost_compile_inputs *inputs,
+                         struct panfrost_compile_inputs *inputs,
                          struct util_dynarray *binary,
                          struct pan_shader_info *info);
 
diff --git a/src/panfrost/midgard/midgard_compile.c 
b/src/panfrost/midgard/midgard_compile.c
index 5e6b6e0c442..803b16b7bd8 100644
--- a/src/panfrost/midgard/midgard_compile.c
+++ b/src/panfrost/midgard/midgard_compile.c
@@ -3088,7 +3088,8 @@ midgard_compile_shader_nir(nir_shader *nir,
 
         unsigned pan_quirks = panfrost_get_quirks(inputs->gpu_id, 0);
         NIR_PASS_V(nir, pan_lower_framebuffer,
-                   inputs->rt_formats, inputs->is_blend, pan_quirks);
+                   inputs->rt_formats, inputs->raw_fmt_mask,
+                   inputs->is_blend, pan_quirks);
 
         NIR_PASS_V(nir, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
                         glsl_type_size, 0);
diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h
index c4425c49b2d..b1f9f83d283 100644
--- a/src/panfrost/util/pan_ir.h
+++ b/src/panfrost/util/pan_ir.h
@@ -131,6 +131,7 @@ struct panfrost_compile_inputs {
         bool no_ubo_to_push;
 
         enum pipe_format rt_formats[8];
+        uint8_t raw_fmt_mask;
         unsigned nr_cbufs;
 
         union {
diff --git a/src/panfrost/util/pan_lower_framebuffer.c 
b/src/panfrost/util/pan_lower_framebuffer.c
index a659ccdb52d..07318666e08 100644
--- a/src/panfrost/util/pan_lower_framebuffer.c
+++ b/src/panfrost/util/pan_lower_framebuffer.c
@@ -196,6 +196,36 @@ pan_unpack_pure_16(nir_builder *b, nir_ssa_def *pack, 
unsigned num_components)
         return nir_pad_vec4(b, nir_vec(b, unpacked, num_components));
 }
 
+static nir_ssa_def *
+pan_pack_reorder(nir_builder *b,
+                 const struct util_format_description *desc,
+                 nir_ssa_def *v)
+{
+        unsigned swizzle[4] = { 0, 1, 2, 3 };
+
+        for (unsigned i = 0; i < v->num_components; i++) {
+                if (desc->swizzle[i] <= PIPE_SWIZZLE_W)
+                        swizzle[i] = desc->swizzle[i];
+        }
+
+        return nir_swizzle(b, v, swizzle, v->num_components);
+}
+
+static nir_ssa_def *
+pan_unpack_reorder(nir_builder *b,
+                   const struct util_format_description *desc,
+                   nir_ssa_def *v)
+{
+        unsigned swizzle[4] = { 0, 1, 2, 3 };
+
+        for (unsigned i = 0; i < v->num_components; i++) {
+                if (desc->swizzle[i] <= PIPE_SWIZZLE_W)
+                        swizzle[desc->swizzle[i]] = i;
+        }
+
+        return nir_swizzle(b, v, swizzle, v->num_components);
+}
+
 static nir_ssa_def *
 pan_replicate_4(nir_builder *b, nir_ssa_def *v)
 {
@@ -475,10 +505,16 @@ pan_lower_fb_store(nir_shader *shader,
                 nir_builder *b,
                 nir_intrinsic_instr *intr,
                 const struct util_format_description *desc,
+                bool reorder_comps,
                 unsigned quirks)
 {
         /* For stores, add conversion before */
         nir_ssa_def *unpacked = nir_ssa_for_src(b, intr->src[1], 4);
+
+        /* Re-order the components */
+        if (reorder_comps)
+                unpacked = pan_pack_reorder(b, desc, unpacked);
+
         nir_ssa_def *packed = pan_pack(b, desc, unpacked);
 
         nir_store_raw_output_pan(b, packed);
@@ -495,6 +531,7 @@ pan_lower_fb_load(nir_shader *shader,
                 nir_builder *b,
                 nir_intrinsic_instr *intr,
                 const struct util_format_description *desc,
+                bool reorder_comps,
                 unsigned base, int sample, unsigned quirks)
 {
         nir_ssa_def *packed =
@@ -524,12 +561,16 @@ pan_lower_fb_load(nir_shader *shader,
         unpacked = nir_convert_to_bit_size(b, unpacked, src_type, bits);
         unpacked = nir_pad_vector(b, unpacked, 
nir_dest_num_components(intr->dest));
 
+        /* Reorder the components */
+        if (reorder_comps)
+                unpacked = pan_unpack_reorder(b, desc, unpacked);
+
         nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, unpacked, 
&intr->instr);
 }
 
 bool
 pan_lower_framebuffer(nir_shader *shader, const enum pipe_format *rt_fmts,
-                      bool is_blend, unsigned quirks)
+                      uint8_t raw_fmt_mask, bool is_blend, unsigned quirks)
 {
         if (shader->info.stage != MESA_SHADER_FRAGMENT)
                return false;
@@ -579,16 +620,17 @@ pan_lower_framebuffer(nir_shader *shader, const enum 
pipe_format *rt_fmts,
                                  * MSAA blend shaders are not yet handled, so
                                  * for now always load sample 0. */
                                 int sample = is_blend ? 0 : -1;
+                                bool reorder_comps = raw_fmt_mask & 
BITFIELD_BIT(rt);
 
                                 nir_builder b;
                                 nir_builder_init(&b, func->impl);
 
                                 if (is_store) {
                                         b.cursor = nir_before_instr(instr);
-                                        pan_lower_fb_store(shader, &b, intr, 
desc, quirks);
+                                        pan_lower_fb_store(shader, &b, intr, 
desc, reorder_comps, quirks);
                                 } else {
                                         b.cursor = nir_after_instr(instr);
-                                        pan_lower_fb_load(shader, &b, intr, 
desc, base, sample, quirks);
+                                        pan_lower_fb_load(shader, &b, intr, 
desc, reorder_comps, base, sample, quirks);
                                 }
 
                                 nir_instr_remove(instr);
diff --git a/src/panfrost/util/pan_lower_framebuffer.h 
b/src/panfrost/util/pan_lower_framebuffer.h
index 5491cd346b1..93f448e34a6 100644
--- a/src/panfrost/util/pan_lower_framebuffer.h
+++ b/src/panfrost/util/pan_lower_framebuffer.h
@@ -41,7 +41,9 @@ enum pan_format_class {
 
 nir_alu_type pan_unpacked_type_for_format(const struct util_format_description 
*desc);
 
-bool pan_lower_framebuffer(nir_shader *shader, const enum pipe_format *rt_fmts,
+bool pan_lower_framebuffer(nir_shader *shader,
+                           const enum pipe_format *rt_fmts,
+                           uint8_t raw_fmt_mask,
                            bool is_blend, unsigned quirks);
 
 #endif

Reply via email to