[Mesa-dev] [PATCH 1/2] llvmpipe: fix blending with SRC_ALPHA_SATURATE with some formats without alpha
Zack Rusin
zackr at vmware.com
Wed Jul 17 22:32:30 PDT 2013
Looks good to me.
----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
>
> We were fixing up the blend factor to ZERO, however this only works correctly
> with fixed point render buffers where the input values are clamped to 0/1
> (because src_alpha_saturate is min(As, 1-Ad) so can be negative with
> unclamped
> inputs). Haven't seen any failure anywhere due to that with fixed point SNORM
> buffers (which clamp inputs to -1/1) but it should apply there as well (snorm
> blending is rare, even opengl 4.3 doesn't require snorm rendertargets at all,
> d3d10 requires them but they are not blendable).
> Doesn't look like piglit hits this though (some internal testing hits the
> float case at least). (With legacy OpenGL we could theoretically still use
> the
> fixup to zero if the fragment color clamp is enabled, but we can't detect
> that
> easily since we don't support native clamping hence it gets baked into the
> shader.)
> ---
> src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c | 18 ++++++++++++++----
> src/gallium/drivers/llvmpipe/lp_state_fs.c | 16 ++++++++++++----
> 2 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> index c4d04a2..377eaa5 100644
> --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> @@ -114,10 +114,20 @@ lp_build_blend_factor_unswizzled(struct
> lp_build_blend_aos_context *bld,
> if(alpha)
> return bld->base.one;
> else {
> - if(!bld->inv_dst)
> - bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
> - if(!bld->saturate)
> - bld->saturate = lp_build_min(&bld->base, src_alpha,
> bld->inv_dst);
> + /*
> + * if there's separate src_alpha there's no dst alpha hence the
> complement
> + * is zero but for unclamped float inputs min can be non-zero
> (negative).
> + */
> + if (bld->src_alpha) {
> + if (!bld->saturate)
> + bld->saturate = lp_build_min(&bld->base, src_alpha,
> bld->base.zero);
> + }
> + else {
> + if(!bld->inv_dst)
> + bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
> + if(!bld->saturate)
> + bld->saturate = lp_build_min(&bld->base, src_alpha,
> bld->inv_dst);
> + }
> return bld->saturate;
> }
> case PIPE_BLENDFACTOR_CONST_COLOR:
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c
> b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> index afd01e3..a305109 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> @@ -2607,7 +2607,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
> * Return the blend factor equivalent to a destination alpha of one.
> */
> static INLINE unsigned
> -force_dst_alpha_one(unsigned factor)
> +force_dst_alpha_one(unsigned factor, boolean clamped_zero)
> {
> switch(factor) {
> case PIPE_BLENDFACTOR_DST_ALPHA:
> @@ -2615,7 +2615,10 @@ force_dst_alpha_one(unsigned factor)
> case PIPE_BLENDFACTOR_INV_DST_ALPHA:
> return PIPE_BLENDFACTOR_ZERO;
> case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
> - return PIPE_BLENDFACTOR_ZERO;
> + if (clamped_zero)
> + return PIPE_BLENDFACTOR_ZERO;
> + else
> + return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
> }
>
> return factor;
> @@ -2735,8 +2738,13 @@ make_variant_key(struct llvmpipe_context *lp,
> */
> if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W ||
> format_desc->swizzle[3] == format_desc->swizzle[0]) {
> - blend_rt->rgb_src_factor =
> force_dst_alpha_one(blend_rt->rgb_src_factor);
> - blend_rt->rgb_dst_factor =
> force_dst_alpha_one(blend_rt->rgb_dst_factor);
> + /* Doesn't cover mixed snorm/unorm but can't render to them anyway
> */
> + boolean clamped_zero = !util_format_is_float(format) &&
> + !util_format_is_snorm(format);
> + blend_rt->rgb_src_factor =
> force_dst_alpha_one(blend_rt->rgb_src_factor,
> + clamped_zero);
> + blend_rt->rgb_dst_factor =
> force_dst_alpha_one(blend_rt->rgb_dst_factor,
> + clamped_zero);
> blend_rt->alpha_func = blend_rt->rgb_func;
> blend_rt->alpha_src_factor = blend_rt->rgb_src_factor;
> blend_rt->alpha_dst_factor = blend_rt->rgb_dst_factor;
> --
> 1.7.9.5
>
More information about the mesa-dev
mailing list