When faking an RGB format with an RGBA format, there may be a channel of data containing garbage. st/mesa already overrides texture swizzles to replace the A channel with ONE. This patch makes it override blend factors to achieve a similar effect.
It appears that st_update_blend is already called when the framebuffer is changed, so it should be safe to look at the render target formats without adding additional state dependencies. --- src/mesa/state_tracker/st_atom_blend.c | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 804de2f154f..3e6e4411107 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -41,6 +41,7 @@ #include "framebuffer.h" #include "main/blend.h" +#include "main/glformats.h" #include "main/macros.h" /** @@ -142,6 +143,28 @@ blend_per_rt(const struct gl_context *ctx, unsigned num_cb) return GL_FALSE; } +/** + * Modify blend function to force destination alpha to 1.0 + * + * If \c function specifies a blend function that uses destination alpha, + * replace it with a function that hard-wires destination alpha to 1.0. This + * is used when rendering to xRGB targets. + */ +static enum pipe_blendfactor +fix_xrgb_alpha(enum pipe_blendfactor factor) +{ + switch (factor) { + case PIPE_BLENDFACTOR_DST_ALPHA: + return PIPE_BLENDFACTOR_ONE; + + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return PIPE_BLENDFACTOR_ZERO; + default: + return factor; + } +} + void st_update_blend( struct st_context *st ) { @@ -210,6 +233,18 @@ st_update_blend( struct st_context *st ) blend->rt[i].alpha_dst_factor = translate_blend(ctx->Color.Blend[j].DstA); } + + const struct gl_renderbuffer *rb = + ctx->DrawBuffer->_ColorDrawBuffers[i]; + + if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, + GL_TEXTURE_ALPHA_TYPE)) { + struct pipe_rt_blend_state *rt = &blend->rt[i]; + rt->rgb_src_factor = fix_xrgb_alpha(rt->rgb_src_factor); + rt->rgb_dst_factor = fix_xrgb_alpha(rt->rgb_dst_factor); + rt->alpha_src_factor = fix_xrgb_alpha(rt->alpha_src_factor); + rt->alpha_dst_factor = fix_xrgb_alpha(rt->alpha_dst_factor); + } } } else { -- 2.18.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev