a2xx: fix DST_ALPHA blending for non-alpha formats
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 25 Aug 2017 04:13:32 +0000 (00:13 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 25 Aug 2017 04:18:34 +0000 (00:18 -0400)
If we're rendering to a format without alpha, convert DST_ALPHA blend to
a ONE so that factors are properly computed. This same workaround is
done on a3xx+ as well.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a2xx/fd2_blend.c
src/gallium/drivers/freedreno/a2xx/fd2_blend.h
src/gallium/drivers/freedreno/a2xx/fd2_emit.c

index eae47ad061f3da6cd2699eb8bf8e09c012583646..4e991794f072cc701eafc8b9b091d98323459c54 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include "pipe/p_state.h"
+#include "util/u_blend.h"
 #include "util/u_string.h"
 #include "util/u_memory.h"
 
@@ -79,14 +80,21 @@ fd2_blend_state_create(struct pipe_context *pctx,
 
        so->rb_colorcontrol = A2XX_RB_COLORCONTROL_ROP_CODE(rop);
 
-       so->rb_blendcontrol =
+       so->rb_blendcontrol_rgb =
                A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(fd_blend_factor(rt->rgb_src_factor)) |
                A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(blend_func(rt->rgb_func)) |
-               A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(fd_blend_factor(rt->rgb_dst_factor)) |
+               A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(fd_blend_factor(rt->rgb_dst_factor));
+
+       so->rb_blendcontrol_alpha =
                A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(fd_blend_factor(rt->alpha_src_factor)) |
                A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(blend_func(rt->alpha_func)) |
                A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(fd_blend_factor(rt->alpha_dst_factor));
 
+       so->rb_blendcontrol_no_alpha_rgb =
+               A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_src_factor))) |
+               A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(blend_func(rt->rgb_func)) |
+               A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_dst_factor)));
+
        if (rt->colormask & PIPE_MASK_R)
                so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_RED;
        if (rt->colormask & PIPE_MASK_G)
index 3c8d8f7c09fb2f265d1c516863f30df39dbeb52e..1d3d2fb7676ebda96cd6ae03f771f74015aa91e8 100644 (file)
@@ -34,7 +34,9 @@
 
 struct fd2_blend_stateobj {
        struct pipe_blend_state base;
-       uint32_t rb_blendcontrol;
+       uint32_t rb_blendcontrol_rgb;
+       uint32_t rb_blendcontrol_alpha;
+       uint32_t rb_blendcontrol_no_alpha_rgb;
        uint32_t rb_colorcontrol;   /* must be OR'd w/ zsa->rb_colorcontrol */
        uint32_t rb_colormask;
 };
index 44f9b55f1fee3c2726c3f53a45fe7ed7aafa0ae2..5a1db1335e342c119830f56f19201a40618d150f 100644 (file)
@@ -299,10 +299,16 @@ fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
                OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol);
        }
 
-       if (dirty & FD_DIRTY_BLEND) {
+       if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) {
+               enum pipe_format format =
+                       pipe_surface_format(ctx->batch->framebuffer.cbufs[0]);
+               bool has_alpha = util_format_has_alpha(format);
+
                OUT_PKT3(ring, CP_SET_CONSTANT, 2);
                OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
-               OUT_RING(ring, blend->rb_blendcontrol);
+               OUT_RING(ring, blend->rb_blendcontrol_alpha |
+                       COND(has_alpha, blend->rb_blendcontrol_rgb) |
+                       COND(!has_alpha, blend->rb_blendcontrol_no_alpha_rgb));
 
                OUT_PKT3(ring, CP_SET_CONSTANT, 2);
                OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));