freedreno/a4xx: fix dst_alpha blend for RGBX render targets
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 20 Nov 2015 18:45:18 +0000 (13:45 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 20 Nov 2015 22:44:10 +0000 (17:44 -0500)
There are not native RGBX render formats, so we must manually force
dst_alpha to be one, same as for a3xx.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a4xx/fd4_blend.c
src/gallium/drivers/freedreno/a4xx/fd4_blend.h
src/gallium/drivers/freedreno/a4xx/fd4_emit.c

index d5e823ef69d22f265635c654799793c35c588e68..e9a9ac19b796c72d53e991d99ff93b38cf633936 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"
 
@@ -98,14 +99,22 @@ fd4_blend_state_create(struct pipe_context *pctx,
                else
                        rt = &cso->rt[0];
 
-               so->rb_mrt[i].blend_control =
+               so->rb_mrt[i].blend_control_rgb =
                                A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(rt->rgb_src_factor)) |
                                A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
-                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor)) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor));
+
+               so->rb_mrt[i].blend_control_alpha =
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(fd_blend_factor(rt->alpha_src_factor)) |
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(blend_func(rt->alpha_func)) |
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(fd_blend_factor(rt->alpha_dst_factor));
 
+               so->rb_mrt[i].blend_control_no_alpha_rgb =
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_src_factor))) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_dst_factor)));
+
+
                so->rb_mrt[i].control =
                                0xc00 | /* XXX ROP_CODE ?? */
                                A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
index 7620d00a625bf092119312f0c212e57549f7d6ed..6230fa7a50edae516e8081f2ac680774e4818fe3 100644 (file)
@@ -39,7 +39,12 @@ struct fd4_blend_stateobj {
        struct {
                uint32_t control;
                uint32_t buf_info;
-               uint32_t blend_control;
+               /* Blend control bits for color if there is an alpha channel */
+               uint32_t blend_control_rgb;
+               /* Blend control bits for color if there is no alpha channel */
+               uint32_t blend_control_no_alpha_rgb;
+               /* Blend control bits for alpha channel */
+               uint32_t blend_control_alpha;
        } rb_mrt[A4XX_MAX_RENDER_TARGETS];
        uint32_t rb_fs_output;
 };
index 5a7b192f79d693f7aa3f12d3f2ad160929c23290..99d1602d74bdae858343183aabd034a6731b1aeb 100644 (file)
@@ -626,11 +626,24 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                uint32_t i;
 
                for (i = 0; i < A4XX_MAX_RENDER_TARGETS; i++) {
+                       enum pipe_format format = pipe_surface_format(
+                                       ctx->framebuffer.cbufs[i]);
+                       bool has_alpha = util_format_has_alpha(format);
+                       uint32_t control = blend->rb_mrt[i].control;
+                       uint32_t blend_control = blend->rb_mrt[i].blend_control_alpha;
+
+                       if (has_alpha) {
+                               blend_control |= blend->rb_mrt[i].blend_control_rgb;
+                       } else {
+                               blend_control |= blend->rb_mrt[i].blend_control_no_alpha_rgb;
+                               control &= ~A4XX_RB_MRT_CONTROL_BLEND2;
+                       }
+
                        OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
-                       OUT_RING(ring, blend->rb_mrt[i].control);
+                       OUT_RING(ring, control);
 
                        OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);
-                       OUT_RING(ring, blend->rb_mrt[i].blend_control);
+                       OUT_RING(ring, blend_control);
                }
 
                OUT_PKT0(ring, REG_A4XX_RB_FS_OUTPUT, 1);