Mesa (main): panfrost: Handle non-dithered clear colours

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Aug 19 00:45:24 UTC 2021


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

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Wed Aug 18 22:16:56 2021 +0000

panfrost: Handle non-dithered clear colours

In b9c095cc2c6 ("panfrost: Rewrite the clear colour packing code"),
packing of clear colours was corrected to use the tilebuffer's
fractional bits, fixing dithering of the clear colour with formats like
RGB565. Unfortunately, that commit did so unconditionally. If the
framebuffer is dithered, but dithering is disabled at the time of
the clear, we would incorrectly dither the clear.

This is a regression, as the old (broken) code passed the relevant CTS
test. What's the catch? Depending on dither state, there are two
formulas to pack tilebuffer colours. We need to handle both. Fixes
KHR-GLES31.core.draw_buffers_indexed.color_masks.

Fixes: b9c095cc2c6 ("panfrost: Rewrite the clear colour packing code")
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12460>

---

 src/gallium/drivers/panfrost/pan_job.c |  2 +-
 src/panfrost/lib/pan_clear.c           | 28 +++++++++++++++++++---------
 src/panfrost/lib/pan_util.h            |  3 ++-
 src/panfrost/lib/tests/test-clear.c    |  2 +-
 src/panfrost/vulkan/panvk_cmd_buffer.c |  2 +-
 5 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 3fd8c5ce28e..620b9d19b5d 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -936,7 +936,7 @@ panfrost_batch_clear(struct panfrost_batch *batch,
                                 continue;
 
                         enum pipe_format format = ctx->pipe_framebuffer.cbufs[i]->format;
-                        pan_pack_color(batch->clear_color[i], color, format);
+                        pan_pack_color(batch->clear_color[i], color, format, false);
                 }
         }
 
diff --git a/src/panfrost/lib/pan_clear.c b/src/panfrost/lib/pan_clear.c
index 6247348565d..f67af951130 100644
--- a/src/panfrost/lib/pan_clear.c
+++ b/src/panfrost/lib/pan_clear.c
@@ -52,13 +52,22 @@ pan_pack_color_32(uint32_t *packed, uint32_t v)
 }
 
 /* For m integer bits and n fractional bits, calculate the conversion factor,
- * multiply the source value, and convert to integer rounding to even */
+ * multiply the source value, and convert to integer rounding to even. When
+ * dithering, the fractional bits are used. When not dithered, only the integer
+ * bits are used and the fractional bits must remain zero. */
 
 static inline uint32_t
-float_to_fixed(float f, unsigned bits_int, unsigned bits_frac)
+float_to_fixed(float f, unsigned bits_int, unsigned bits_frac, bool dither)
 {
-        float factor = ((1 << bits_int) - 1) << bits_frac;
-        return _mesa_roundevenf(f * factor);
+        uint32_t m = (1 << bits_int) - 1;
+
+        if (dither) {
+                float factor = m << bits_frac;
+                return _mesa_roundevenf(f * factor);
+        } else {
+                uint32_t v = _mesa_roundevenf(f * (float) m);
+                return v << bits_frac;
+        }
 }
 
 /* These values are shared across hardware versions. Don't include GenXML. */
@@ -116,7 +125,8 @@ pan_pack_raw(uint32_t *packed, const union pipe_color_union *color, enum pipe_fo
 }
 
 void
-pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_format format)
+pan_pack_color(uint32_t *packed, const union pipe_color_union *color,
+               enum pipe_format format, bool dithered)
 {
         /* Set of blendable formats is common across versions. TODO: v9 */
         enum mali_color_buffer_internal_format internal =
@@ -157,10 +167,10 @@ pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_
         assert(count_a == 32);
 
         /* Convert the transformed float colour to the given layout */
-        uint32_t ur = float_to_fixed(r, l.int_r, l.frac_r) << 0;
-        uint32_t ug = float_to_fixed(g, l.int_g, l.frac_g) << count_r;
-        uint32_t ub = float_to_fixed(b, l.int_b, l.frac_b) << count_g;
-        uint32_t ua = float_to_fixed(a, l.int_a, l.frac_a) << count_b;
+        uint32_t ur = float_to_fixed(r, l.int_r, l.frac_r, dithered) << 0;
+        uint32_t ug = float_to_fixed(g, l.int_g, l.frac_g, dithered) << count_r;
+        uint32_t ub = float_to_fixed(b, l.int_b, l.frac_b, dithered) << count_g;
+        uint32_t ua = float_to_fixed(a, l.int_a, l.frac_a, dithered) << count_b;
 
         pan_pack_color_32(packed, ur | ug | ub | ua);
 }
diff --git a/src/panfrost/lib/pan_util.h b/src/panfrost/lib/pan_util.h
index 099f4d75076..6af0ac2887e 100644
--- a/src/panfrost/lib/pan_util.h
+++ b/src/panfrost/lib/pan_util.h
@@ -61,6 +61,7 @@ panfrost_format_to_bifrost_blend(const struct panfrost_device *dev,
                                  bool dithered);
 
 void
-pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_format format);
+pan_pack_color(uint32_t *packed, const union pipe_color_union *color,
+               enum pipe_format format, bool dithered);
 
 #endif /* PAN_UTIL_H */
diff --git a/src/panfrost/lib/tests/test-clear.c b/src/panfrost/lib/tests/test-clear.c
index 5a4a235dc7b..85fde4fa7f0 100644
--- a/src/panfrost/lib/tests/test-clear.c
+++ b/src/panfrost/lib/tests/test-clear.c
@@ -115,7 +115,7 @@ int main(int argc, const char **argv)
    for (unsigned i = 0; i < ARRAY_SIZE(clear_tests); ++i) {
       struct test T = clear_tests[i];
       uint32_t packed[4];
-      pan_pack_color(&packed[0], &T.colour, T.format);
+      pan_pack_color(&packed[0], &T.colour, T.format, T.dithered);
 
       ASSERT_EQ(T.packed, packed);
    }
diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c
index 3a19c93ab99..c753c688db5 100644
--- a/src/panfrost/vulkan/panvk_cmd_buffer.c
+++ b/src/panfrost/vulkan/panvk_cmd_buffer.c
@@ -593,7 +593,7 @@ panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
           }
        } else if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
           union pipe_color_union *col = (union pipe_color_union *) &in[i].color;
-          pan_pack_color(cmdbuf->state.clear[i].color, col, fmt);
+          pan_pack_color(cmdbuf->state.clear[i].color, col, fmt, false);
        }
    }
 }



More information about the mesa-commit mailing list