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 <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin 2017-08-25 00:13:32 -04:00
parent f3bde890cd
commit f623e1742f
3 changed files with 21 additions and 5 deletions

View 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)

View 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;
};

View 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));