aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2017-08-25 00:13:32 -0400
committerIlia Mirkin <[email protected]>2017-08-25 00:18:34 -0400
commitf623e1742f20cffe2c91287ab6b0b0a39a78e02c (patch)
treefc4a1d65db1a683df2a38a92e35e4e211a4445de /src/gallium
parentf3bde890cde869d8ba4280186a4de6dd677b387a (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_blend.c12
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_blend.h4
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.c10
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));