Mesa (master): i965: Clamp clear colors to the representable range

Jason Ekstrand jekstrand at kemper.freedesktop.org
Fri Jun 23 19:30:55 UTC 2017


Module: Mesa
Branch: master
Commit: f1fa4be871e13c68b50685aaf64dc095b49ed0b5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f1fa4be871e13c68b50685aaf64dc095b49ed0b5

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Fri Jun 16 00:13:45 2017 -0700

i965: Clamp clear colors to the representable range

Starting with Sky Lake, we can clear to arbitrary floats or integers.
Unfortunately, the hardware isn't particularly smart when it comes
sampling from that clear color.  If the clear color is out of range for
the surface format, it will happily return whatever we put in the
surface state packet unmodified.  In order to avoid returning bogus
values for surfaces with a limited range, we need to do some clamping.

Cc: "17.1" <mesa-stable at lists.freedesktop.org>
Reviewed-by: Chad Versace <chadversary at chromium.org>

---

 src/mesa/drivers/dri/i965/brw_meta_util.c | 40 +++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c
index 575f437750..f9fd350918 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_util.c
+++ b/src/mesa/drivers/dri/i965/brw_meta_util.c
@@ -364,6 +364,46 @@ brw_meta_convert_fast_clear_color(const struct brw_context *brw,
       break;
    }
 
+   switch (_mesa_get_format_datatype(mt->format)) {
+   case GL_UNSIGNED_NORMALIZED:
+      for (int i = 0; i < 4; i++)
+         override_color.f32[i] = CLAMP(override_color.f32[i], 0.0f, 1.0f);
+      break;
+
+   case GL_SIGNED_NORMALIZED:
+      for (int i = 0; i < 4; i++)
+         override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f);
+      break;
+
+   case GL_UNSIGNED_INT:
+      for (int i = 0; i < 4; i++) {
+         unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i);
+         if (bits < 32) {
+            uint32_t max = (1u << bits) - 1;
+            override_color.u32[i] = MIN2(override_color.u32[i], max);
+         }
+      }
+      break;
+
+   case GL_INT:
+      for (int i = 0; i < 4; i++) {
+         unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i);
+         if (bits < 32) {
+            int32_t max = (1 << (bits - 1)) - 1;
+            int32_t min = -(1 << (bits - 1));
+            override_color.i32[i] = CLAMP(override_color.i32[i], min, max);
+         }
+      }
+      break;
+
+   case GL_FLOAT:
+      if (!_mesa_is_format_signed(mt->format)) {
+         for (int i = 0; i < 4; i++)
+            override_color.f32[i] = MAX2(override_color.f32[i], 0.0f);
+      }
+      break;
+   }
+
    if (!_mesa_format_has_color_component(mt->format, 3)) {
       if (_mesa_is_format_integer_color(mt->format))
          override_color.u32[3] = 1;




More information about the mesa-commit mailing list