mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 10:40:11 +01:00
freedreno/a3xx: fix alpha-blending on RGBX formats
Expert debugging assistance provided by Chris Forbes. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
parent
6b01969345
commit
97fef2db5c
5 changed files with 55 additions and 8 deletions
|
|
@ -168,6 +168,7 @@ C_SOURCES := \
|
|||
util/u_atomic.h \
|
||||
util/u_bitmask.c \
|
||||
util/u_bitmask.h \
|
||||
util/u_blend.h \
|
||||
util/u_blit.c \
|
||||
util/u_blit.h \
|
||||
util/u_blitter.c \
|
||||
|
|
|
|||
25
src/gallium/auxiliary/util/u_blend.h
Normal file
25
src/gallium/auxiliary/util/u_blend.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef U_BLEND_H
|
||||
#define U_BLEND_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
/**
|
||||
* When faking RGBX render target formats with RGBA ones, the blender is still
|
||||
* supposed to treat the destination's alpha channel as 1 instead of the
|
||||
* garbage that's there. Return a blend factor that will take that into
|
||||
* account.
|
||||
*/
|
||||
static INLINE int
|
||||
util_blend_dst_alpha_to_one(int factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
return PIPE_BLENDFACTOR_ONE;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
return PIPE_BLENDFACTOR_ZERO;
|
||||
default:
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* U_BLEND_H */
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_blend.h"
|
||||
#include "util/u_string.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
|
@ -99,14 +100,21 @@ fd3_blend_state_create(struct pipe_context *pctx,
|
|||
for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) {
|
||||
const struct pipe_rt_blend_state *rt = &cso->rt[i];
|
||||
|
||||
so->rb_mrt[i].blend_control =
|
||||
so->rb_mrt[i].blend_control_rgb =
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(rt->rgb_src_factor)) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor)) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor));
|
||||
|
||||
so->rb_mrt[i].blend_control_alpha =
|
||||
A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(fd_blend_factor(rt->alpha_src_factor)) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(blend_func(rt->alpha_func)) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(fd_blend_factor(rt->alpha_dst_factor));
|
||||
|
||||
so->rb_mrt[i].blend_control_no_alpha_rgb =
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_src_factor))) |
|
||||
A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
|
||||
A3XX_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 =
|
||||
A3XX_RB_MRT_CONTROL_ROP_CODE(rop) |
|
||||
A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,12 @@
|
|||
struct fd3_blend_stateobj {
|
||||
struct pipe_blend_state base;
|
||||
struct {
|
||||
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;
|
||||
uint32_t control;
|
||||
} rb_mrt[4];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -571,11 +571,12 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(blend->rb_mrt); i++) {
|
||||
bool is_float = util_format_is_float(
|
||||
pipe_surface_format(ctx->framebuffer.cbufs[i]));
|
||||
bool is_int = util_format_is_pure_integer(
|
||||
pipe_surface_format(ctx->framebuffer.cbufs[i]));
|
||||
enum pipe_format format = pipe_surface_format(ctx->framebuffer.cbufs[i]);
|
||||
bool is_float = util_format_is_float(format);
|
||||
bool is_int = util_format_is_pure_integer(format);
|
||||
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 (is_int) {
|
||||
control &= (A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK |
|
||||
|
|
@ -583,11 +584,18 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
control |= A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY);
|
||||
}
|
||||
|
||||
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 &= ~A3XX_RB_MRT_CONTROL_BLEND2;
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
|
||||
OUT_RING(ring, control);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
|
||||
OUT_RING(ring, blend->rb_mrt[i].blend_control |
|
||||
OUT_RING(ring, blend_control |
|
||||
COND(!is_float, A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue