i965: Handle lum, intensity and missing components in the fast clear
authorNeil Roberts <neil@linux.intel.com>
Wed, 4 Nov 2015 14:52:06 +0000 (15:52 +0100)
committerNeil Roberts <neil@linux.intel.com>
Mon, 23 Nov 2015 09:44:01 +0000 (10:44 +0100)
It looks like the sampler hardware doesn't take into account the
surface format when sampling a cleared color after a fast clear has
been done. So for example if you clear a GL_RED surface to 1,1,1,1
then the sampling instructions will return 1,1,1,1 instead of 1,0,0,1.
This patch makes it override the color that is programmed in the
surface state in order to swizzle for luminance and intensity as well
as overriding the missing components.

Fixes the ext_framebuffer_multisample-fast-clear Piglit test.

v2: Handle luminance and intensity formats
Reviewed-by: Ben Widawsky <benjamin.widawsky@intel.com>
src/mesa/drivers/dri/i965/brw_meta_fast_clear.c

index 499daba3b009b8574186e360f6c0f6af1d6accd2..1f8bfdfa4923ae1043e1862ed0eeab618400d6a3 100644 (file)
@@ -380,13 +380,43 @@ set_fast_clear_color(struct brw_context *brw,
                      struct intel_mipmap_tree *mt,
                      const union gl_color_union *color)
 {
+   union gl_color_union override_color = *color;
+
+   /* The sampler doesn't look at the format of the surface when the fast
+    * clear color is used so we need to implement luminance, intensity and
+    * missing components manually.
+    */
+   switch (_mesa_get_format_base_format(mt->format)) {
+   case GL_INTENSITY:
+      override_color.ui[3] = override_color.ui[0];
+      /* flow through */
+   case GL_LUMINANCE:
+   case GL_LUMINANCE_ALPHA:
+      override_color.ui[1] = override_color.ui[0];
+      override_color.ui[2] = override_color.ui[0];
+      break;
+   default:
+      for (int i = 0; i < 3; i++) {
+         if (!_mesa_format_has_color_component(mt->format, i))
+            override_color.ui[i] = 0;
+      }
+      break;
+   }
+
+   if (!_mesa_format_has_color_component(mt->format, 3)) {
+      if (_mesa_is_format_integer_color(mt->format))
+         override_color.ui[3] = 1;
+      else
+         override_color.f[3] = 1.0f;
+   }
+
    if (brw->gen >= 9) {
-      mt->gen9_fast_clear_color = *color;
+      mt->gen9_fast_clear_color = override_color;
    } else {
       mt->fast_clear_color_value = 0;
       for (int i = 0; i < 4; i++) {
          /* Testing for non-0 works for integer and float colors */
-         if (color->f[i] != 0.0f) {
+         if (override_color.f[i] != 0.0f) {
              mt->fast_clear_color_value |=
                 1 << (GEN7_SURFACE_CLEAR_COLOR_SHIFT + (3 - i));
          }