vc4: Colormask should apply after all other fragment ops (like logic op).
authorEric Anholt <eric@anholt.net>
Mon, 12 Jan 2015 01:53:48 +0000 (14:53 +1300)
committerEric Anholt <eric@anholt.net>
Thu, 15 Jan 2015 09:19:25 +0000 (22:19 +1300)
Theoretically it should apply after dithering as well, but ditehring for
565 happens in fixed function in the TLB store.

src/gallium/drivers/vc4/vc4_program.c

index ff2bdf2..0fa43e2 100644 (file)
@@ -1804,15 +1804,6 @@ emit_frag_end(struct vc4_compile *c)
                         blend_color[i] = qir_srgb_encode(c, blend_color[i]);
         }
 
-        /* If the bit isn't set in the color mask, then just return the
-         * original dst color, instead.
-         */
-        for (int i = 0; i < 4; i++) {
-                if (!(c->fs_key->blend.colormask & (1 << i))) {
-                        blend_color[i] = dst_color[i];
-                }
-        }
-
         /* Debug: Sometimes you're getting a black output and just want to see
          * if the FS is getting executed at all.  Spam magenta into the color
          * output.
@@ -1875,6 +1866,24 @@ emit_frag_end(struct vc4_compile *c)
                 packed_color = vc4_logicop(c, packed_color, packed_dst_color);
         }
 
+        /* If the bit isn't set in the color mask, then just return the
+         * original dst color, instead.
+         */
+        uint32_t colormask = 0xffffffff;
+        for (int i = 0; i < 4; i++) {
+                if (format_swiz[i] < 4 &&
+                    !(c->fs_key->blend.colormask & (1 << format_swiz[i]))) {
+                        colormask &= ~(0xff << (i * 8));
+                }
+        }
+        if (colormask != 0xffffffff) {
+                packed_color = qir_OR(c,
+                                      qir_AND(c, packed_color,
+                                              qir_uniform_ui(c, colormask)),
+                                      qir_AND(c, packed_dst_color,
+                                              qir_uniform_ui(c, ~colormask)));
+        }
+
         qir_emit(c, qir_inst(QOP_TLB_COLOR_WRITE, c->undef,
                              packed_color, c->undef));
 }