fix rewriting of non-alpha formats

When we use independent blending, we need to check every rendertarget
indevidually, not just once for all, otherwise we end up using the
wrong blend-mode for some render-targets.

Fixes these test-cases:
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.0
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.6
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.14

[airlied: rebased onto master hopefully correct]
Signed-off-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
macos/master
Erik Faye-Lund 7 years ago committed by Dave Airlie
parent 8889173cbd
commit 36fe024ab8
  1. 75
      src/vrend_renderer.c

@ -3548,6 +3548,14 @@ static inline int conv_dst_blend(int blend_factor)
return blend_factor;
}
static inline bool is_const_blend(int blend_factor)
{
return (blend_factor == PIPE_BLENDFACTOR_CONST_COLOR ||
blend_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
blend_factor == PIPE_BLENDFACTOR_INV_CONST_COLOR ||
blend_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA);
}
static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_state *state)
{
if (state->logicop_enable != ctx->sub->hw_blend_state.logicop_enable) {
@ -3642,57 +3650,52 @@ static void vrend_patch_blend_state(struct vrend_context *ctx)
{
struct pipe_blend_state new_state = ctx->sub->blend_state;
struct pipe_blend_state *state = &ctx->sub->blend_state;
bool dest_alpha_only = false, dest_has_no_alpha = false;
bool swizzle_blend_color = false;
struct pipe_blend_color blend_color = ctx->sub->blend_color;
int i;
if (ctx->sub->nr_cbufs == 0)
return;
for (i = 0; i < ctx->sub->nr_cbufs; i++) {
if (!ctx->sub->surf[i])
continue;
if (vrend_format_is_emulated_alpha(ctx->sub->surf[i]->format)) {
dest_alpha_only = true;
}
if (!util_format_has_alpha(ctx->sub->surf[i]->format)) {
dest_has_no_alpha = true;
for (i = 0; i < (state->independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1); i++) {
if (i < ctx->sub->nr_cbufs && ctx->sub->surf[i]) {
if (vrend_format_is_emulated_alpha(ctx->sub->surf[i]->format)) {
if (state->rt[i].blend_enable) {
new_state.rt[i].rgb_src_factor = conv_a8_blend(state->rt[i].alpha_src_factor);
new_state.rt[i].rgb_dst_factor = conv_a8_blend(state->rt[i].alpha_dst_factor);
new_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
new_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
}
new_state.rt[i].colormask = 0;
if (state->rt[i].colormask & PIPE_MASK_A)
new_state.rt[i].colormask |= PIPE_MASK_R;
if (is_const_blend(new_state.rt[i].rgb_src_factor) ||
is_const_blend(new_state.rt[i].rgb_dst_factor)) {
swizzle_blend_color = true;
}
} else if (!util_format_has_alpha(ctx->sub->surf[i]->format)) {
if (!(is_dst_blend(state->rt[i].rgb_src_factor) ||
is_dst_blend(state->rt[i].rgb_dst_factor) ||
is_dst_blend(state->rt[i].alpha_src_factor) ||
is_dst_blend(state->rt[i].alpha_dst_factor)))
continue;
new_state.rt[i].rgb_src_factor = conv_dst_blend(state->rt[i].rgb_src_factor);
new_state.rt[i].rgb_dst_factor = conv_dst_blend(state->rt[i].rgb_dst_factor);
new_state.rt[i].alpha_src_factor = conv_dst_blend(state->rt[i].alpha_src_factor);
new_state.rt[i].alpha_dst_factor = conv_dst_blend(state->rt[i].alpha_dst_factor);
}
}
}
if (dest_alpha_only) {
for (i = 0; i < (state->independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1); i++) {
if (state->rt[i].blend_enable) {
new_state.rt[i].rgb_src_factor = conv_a8_blend(state->rt[i].alpha_src_factor);
new_state.rt[i].rgb_dst_factor = conv_a8_blend(state->rt[i].alpha_dst_factor);
new_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
new_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
}
new_state.rt[i].colormask = 0;
if (state->rt[i].colormask & PIPE_MASK_A)
new_state.rt[i].colormask |= PIPE_MASK_R;
}
vrend_hw_emit_blend(ctx, &new_state);
if (swizzle_blend_color) {
blend_color.color[0] = blend_color.color[3];
blend_color.color[1] = 0.0f;
blend_color.color[2] = 0.0f;
blend_color.color[3] = 0.0f;
} else if (dest_has_no_alpha) {
for (i = 0; i < (state->independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1); i++) {
if (!(is_dst_blend(state->rt[i].rgb_src_factor) ||
is_dst_blend(state->rt[i].rgb_dst_factor) ||
is_dst_blend(state->rt[i].alpha_src_factor) ||
is_dst_blend(state->rt[i].alpha_dst_factor)))
continue;
new_state.rt[i].rgb_src_factor = conv_dst_blend(state->rt[i].rgb_src_factor);
new_state.rt[i].rgb_dst_factor = conv_dst_blend(state->rt[i].rgb_dst_factor);
new_state.rt[i].alpha_src_factor = conv_dst_blend(state->rt[i].alpha_src_factor);
new_state.rt[i].alpha_dst_factor = conv_dst_blend(state->rt[i].alpha_dst_factor);
}
}
vrend_hw_emit_blend(ctx, &new_state);
glBlendColor(blend_color.color[0],
blend_color.color[1],
blend_color.color[2],

Loading…
Cancel
Save