broadcom/vc5: Force blending to treat alpha as 1 for formats without alpha.
authorEric Anholt <eric@anholt.net>
Fri, 27 Oct 2017 22:52:22 +0000 (15:52 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 30 Oct 2017 20:31:32 +0000 (13:31 -0700)
Fixes fbo-blending-formats on RGB8 and 565.  We will still need to demote
blending to shader code in the MRT case to fix it in general, but that can
be added when we start doing 32F blending (which also needs to be done in
the shader).

src/gallium/drivers/vc5/vc5_context.h
src/gallium/drivers/vc5/vc5_emit.c
src/gallium/drivers/vc5/vc5_state.c

index 99d170b7dc0f2235893d250e5fbe6e94bd9a1261..2292027819270c15937bc5fbbaf2a50934bc6de3 100644 (file)
@@ -345,6 +345,14 @@ struct vc5_context {
          */
         uint8_t swap_color_rb;
 
+        /* Per render target, whether we should treat the dst alpha values as
+         * one in blending.
+         *
+         * For RGBX formats, the tile buffer's alpha channel will be
+         * undefined.
+         */
+        uint8_t blend_dst_alpha_one;
+
         struct pipe_poly_stipple stipple;
         struct pipe_clip_state clip;
         struct pipe_viewport_state viewport;
index 1368d34729ae3ebbdaf21d099ca0a46c25ffa387..83ea3c475b2571dd0e807482a00f1eae0651b9dd 100644 (file)
@@ -28,7 +28,7 @@
 #include "broadcom/compiler/v3d_compiler.h"
 
 static uint8_t
-vc5_factor(enum pipe_blendfactor factor)
+vc5_factor(enum pipe_blendfactor factor, bool dst_alpha_one)
 {
         /* We may get a bad blendfactor when blending is disabled. */
         if (factor == 0)
@@ -52,9 +52,13 @@ vc5_factor(enum pipe_blendfactor factor)
         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
                 return V3D_BLEND_FACTOR_INV_SRC_ALPHA;
         case PIPE_BLENDFACTOR_DST_ALPHA:
-                return V3D_BLEND_FACTOR_DST_ALPHA;
+                return (dst_alpha_one ?
+                        V3D_BLEND_FACTOR_ONE :
+                        V3D_BLEND_FACTOR_DST_ALPHA);
         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-                return V3D_BLEND_FACTOR_INV_DST_ALPHA;
+                return (dst_alpha_one ?
+                        V3D_BLEND_FACTOR_ZERO :
+                        V3D_BLEND_FACTOR_INV_DST_ALPHA);
         case PIPE_BLENDFACTOR_CONST_COLOR:
                 return V3D_BLEND_FACTOR_CONST_COLOR;
         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
@@ -327,15 +331,19 @@ vc5_emit_state(struct pipe_context *pctx)
 
                         config.colour_blend_mode = rtblend->rgb_func;
                         config.colour_blend_dst_factor =
-                                vc5_factor(rtblend->rgb_dst_factor);
+                                vc5_factor(rtblend->rgb_dst_factor,
+                                           vc5->blend_dst_alpha_one);
                         config.colour_blend_src_factor =
-                                vc5_factor(rtblend->rgb_src_factor);
+                                vc5_factor(rtblend->rgb_src_factor,
+                                           vc5->blend_dst_alpha_one);
 
                         config.alpha_blend_mode = rtblend->alpha_func;
                         config.alpha_blend_dst_factor =
-                                vc5_factor(rtblend->alpha_dst_factor);
+                                vc5_factor(rtblend->alpha_dst_factor,
+                                           vc5->blend_dst_alpha_one);
                         config.alpha_blend_src_factor =
-                                vc5_factor(rtblend->alpha_src_factor);
+                                vc5_factor(rtblend->alpha_src_factor,
+                                           vc5->blend_dst_alpha_one);
                 }
 
                 cl_emit(&job->bcl, COLOUR_WRITE_MASKS, mask) {
index a7717b30dfb30411f321a7bb956f2b1e423f7acb..db921d63f3664e66cc3a69543238a01dea6c58ef 100644 (file)
@@ -389,6 +389,7 @@ vc5_set_framebuffer_state(struct pipe_context *pctx,
         cso->height = framebuffer->height;
 
         vc5->swap_color_rb = 0;
+        vc5->blend_dst_alpha_one = 0;
         for (int i = 0; i < vc5->framebuffer.nr_cbufs; i++) {
                 struct pipe_surface *cbuf = vc5->framebuffer.cbufs[i];
                 const struct util_format_description *desc =
@@ -401,6 +402,9 @@ vc5_set_framebuffer_state(struct pipe_context *pctx,
                     cbuf->format != PIPE_FORMAT_B5G6R5_UNORM) {
                         vc5->swap_color_rb |= 1 << i;
                 }
+
+                if (desc->swizzle[3] == PIPE_SWIZZLE_1)
+                        vc5->blend_dst_alpha_one |= 1 << i;
         }
 
         vc5->dirty |= VC5_DIRTY_FRAMEBUFFER;