From f623e1742f20cffe2c91287ab6b0b0a39a78e02c Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 25 Aug 2017 00:13:32 -0400 Subject: [PATCH] a2xx: fix DST_ALPHA blending for non-alpha formats 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 --- src/gallium/drivers/freedreno/a2xx/fd2_blend.c | 12 ++++++++++-- src/gallium/drivers/freedreno/a2xx/fd2_blend.h | 4 +++- src/gallium/drivers/freedreno/a2xx/fd2_emit.c | 10 ++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_blend.c b/src/gallium/drivers/freedreno/a2xx/fd2_blend.c index eae47ad061f..4e991794f07 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_blend.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_blend.c @@ -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) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_blend.h b/src/gallium/drivers/freedreno/a2xx/fd2_blend.h index 3c8d8f7c09f..1d3d2fb7676 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_blend.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_blend.h @@ -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; }; diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c index 44f9b55f1fe..5a1db1335e3 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c @@ -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)); -- 2.30.2