freedreno/a3xx: color masking works like a blend for some formats
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 25 Apr 2015 19:37:24 +0000 (15:37 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 28 Apr 2015 00:17:07 +0000 (20:17 -0400)
When there is a colormask active that does not cover all the channels,
enable reading in the destination like with a combining blend
operation. This fixes fbo-blending-formats on a3xx.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c

index af08696307574543931d3ead04ff31ad07c99b22..07cc2266d088da3f2e23d4348c4cbef4f3ae9623 100644 (file)
@@ -704,6 +704,8 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 
                for (i = 0; i < ARRAY_SIZE(blend->rb_mrt); i++) {
                        enum pipe_format format = pipe_surface_format(ctx->framebuffer.cbufs[i]);
+                       const struct util_format_description *desc =
+                               util_format_description(format);
                        bool is_float = util_format_is_float(format);
                        bool is_int = util_format_is_pure_integer(format);
                        bool has_alpha = util_format_has_alpha(format);
@@ -726,6 +728,18 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                control &= ~A3XX_RB_MRT_CONTROL_BLEND2;
                        }
 
+                       if (format && util_format_get_component_bits(
+                                               format, UTIL_FORMAT_COLORSPACE_RGB, 0) < 8) {
+                               const struct pipe_rt_blend_state *rt;
+                               if (ctx->blend->independent_blend_enable)
+                                       rt = &ctx->blend->rt[i];
+                               else
+                                       rt = &ctx->blend->rt[0];
+
+                               if (!util_format_colormask_full(desc, rt->colormask))
+                                       control |= A3XX_RB_MRT_CONTROL_READ_DEST_ENABLE;
+                       }
+
                        OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
                        OUT_RING(ring, control);