[Mesa-dev] [PATCH 1/2] llvmpipe: first steps of adding dual source blend support
Jose Fonseca
jfonseca at vmware.com
Fri Feb 8 07:55:20 PST 2013
----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
>
> This adds support of the additional blending factors to the blend function
> itself, and also enables testing of it in lp_test_blend (which passes).
> Still need to add the glue code of linking fs shader outputs to blend inputs
> in llvmpipe, and probably need to add special handling if destination doesn't
> include alpha (which lp_test_blend doesn't test).
> ---
> src/gallium/drivers/llvmpipe/lp_bld_blend.h | 1 +
> src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c | 12 ++--
> src/gallium/drivers/llvmpipe/lp_state_fs.c | 1 +
> src/gallium/drivers/llvmpipe/lp_test_blend.c | 70
> ++++++++++++++++-------
> 4 files changed, 57 insertions(+), 27 deletions(-)
>
> diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h
> b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
> index 394935b..4bd2867 100644
> --- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h
> +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
> @@ -61,6 +61,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
> unsigned rt,
> LLVMValueRef src,
> LLVMValueRef src_alpha,
> + LLVMValueRef src1,
> LLVMValueRef dst,
> LLVMValueRef mask,
> LLVMValueRef const_,
> diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> index ccdf852..8e9e7fe 100644
> --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
> @@ -69,6 +69,7 @@ struct lp_build_blend_aos_context
>
> LLVMValueRef src;
> LLVMValueRef src_alpha;
> + LLVMValueRef src1;
> LLVMValueRef dst;
> LLVMValueRef const_;
> LLVMValueRef const_alpha;
> @@ -123,9 +124,7 @@ lp_build_blend_factor_unswizzled(struct
> lp_build_blend_aos_context *bld,
> return const_alpha;
> case PIPE_BLENDFACTOR_SRC1_COLOR:
> case PIPE_BLENDFACTOR_SRC1_ALPHA:
> - /* TODO */
> - assert(0);
> - return bld->base.zero;
> + return bld->src1;
> case PIPE_BLENDFACTOR_INV_SRC_COLOR:
> if(!bld->inv_src)
> bld->inv_src = lp_build_comp(&bld->base, bld->src);
> @@ -149,9 +148,7 @@ lp_build_blend_factor_unswizzled(struct
> lp_build_blend_aos_context *bld,
> return bld->inv_const_alpha;
> case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
> case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
> - /* TODO */
> - assert(0);
> - return bld->base.zero;
> + return lp_build_comp(&bld->base, bld->src1);
> default:
> assert(0);
> return bld->base.zero;
> @@ -268,6 +265,7 @@ lp_build_blend_factor(struct lp_build_blend_aos_context
> *bld,
> * @param type data type of the pixel vector
> * @param rt render target index
> * @param src blend src
> + * @param src1 second blend src (for dual source blend)
> * @param dst blend dst
> * @param mask optional mask to apply to the blending result
> * @param const_ const blend color
> @@ -283,6 +281,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
> unsigned rt,
> LLVMValueRef src,
> LLVMValueRef src_alpha,
> + LLVMValueRef src1,
> LLVMValueRef dst,
> LLVMValueRef mask,
> LLVMValueRef const_,
> @@ -304,6 +303,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
> memset(&bld, 0, sizeof bld);
> lp_build_context_init(&bld.base, gallivm, type);
> bld.src = src;
> + bld.src1 = src1;
> bld.dst = dst;
> bld.const_ = const_;
> bld.src_alpha = src_alpha;
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c
> b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> index 90a67e6..2b31c14 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> @@ -1693,6 +1693,7 @@ generate_unswizzled_blend(struct gallivm_state
> *gallivm,
> rt,
> src[i],
> has_alpha ? NULL : src_alpha[i],
> + NULL,
> dst[i],
> partial_mask ? src_mask[i] : NULL,
> blend_color,
> diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c
> b/src/gallium/drivers/llvmpipe/lp_test_blend.c
> index 754434d..6faaedf 100644
> --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
> +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
> @@ -45,7 +45,8 @@
> #include "lp_test.h"
>
>
> -typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const
> void *con, void *res);
> +typedef void (*blend_test_ptr_t)(const void *src, const void *src1,
> + const void *dst, const void *con, void
> *res);
>
>
> void
> @@ -138,9 +139,10 @@ add_blend_test(struct gallivm_state *gallivm,
> LLVMModuleRef module = gallivm->module;
> LLVMContextRef context = gallivm->context;
> LLVMTypeRef vec_type;
> - LLVMTypeRef args[4];
> + LLVMTypeRef args[5];
> LLVMValueRef func;
> LLVMValueRef src_ptr;
> + LLVMValueRef src1_ptr;
> LLVMValueRef dst_ptr;
> LLVMValueRef const_ptr;
> LLVMValueRef res_ptr;
> @@ -150,29 +152,32 @@ add_blend_test(struct gallivm_state *gallivm,
> const unsigned rt = 0;
> const unsigned char swizzle[4] = { 0, 1, 2, 3 };
> LLVMValueRef src;
> + LLVMValueRef src1;
> LLVMValueRef dst;
> LLVMValueRef con;
> LLVMValueRef res;
>
> vec_type = lp_build_vec_type(gallivm, type);
>
> - args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
> - func = LLVMAddFunction(module, "test",
> LLVMFunctionType(LLVMVoidTypeInContext(context), args, 4, 0));
> + args[4] = args[3] = args[2] = args[1] = args[0] =
> LLVMPointerType(vec_type, 0);
> + func = LLVMAddFunction(module, "test",
> LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0));
> LLVMSetFunctionCallConv(func, LLVMCCallConv);
> src_ptr = LLVMGetParam(func, 0);
> - dst_ptr = LLVMGetParam(func, 1);
> - const_ptr = LLVMGetParam(func, 2);
> - res_ptr = LLVMGetParam(func, 3);
> + src1_ptr = LLVMGetParam(func, 1);
> + dst_ptr = LLVMGetParam(func, 2);
> + const_ptr = LLVMGetParam(func, 3);
> + res_ptr = LLVMGetParam(func, 4);
>
> block = LLVMAppendBasicBlockInContext(context, func, "entry");
> builder = gallivm->builder;
> LLVMPositionBuilderAtEnd(builder, block);
>
> src = LLVMBuildLoad(builder, src_ptr, "src");
> + src1 = LLVMBuildLoad(builder, src1_ptr, "src1");
> dst = LLVMBuildLoad(builder, dst_ptr, "dst");
> con = LLVMBuildLoad(builder, const_ptr, "const");
>
> - res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL,
> dst, NULL, con, NULL, swizzle, 4);
> + res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL,
> src1, dst, NULL, con, NULL, swizzle, 4);
>
> lp_build_name(res, "res");
>
> @@ -189,6 +194,7 @@ compute_blend_ref_term(unsigned rgb_factor,
> unsigned alpha_factor,
> const double *factor,
> const double *src,
> + const double *src1,
> const double *dst,
> const double *con,
> double *term)
> @@ -238,10 +244,14 @@ compute_blend_ref_term(unsigned rgb_factor,
> term[2] = factor[2] * con[3]; /* B */
> break;
> case PIPE_BLENDFACTOR_SRC1_COLOR:
> - assert(0); /* to do */
> + term[0] = factor[0] * src1[0]; /* R */
> + term[1] = factor[1] * src1[1]; /* G */
> + term[2] = factor[2] * src1[2]; /* B */
> break;
> case PIPE_BLENDFACTOR_SRC1_ALPHA:
> - assert(0); /* to do */
> + term[0] = factor[0] * src1[3]; /* R */
> + term[1] = factor[1] * src1[3]; /* G */
> + term[2] = factor[2] * src1[3]; /* B */
> break;
> case PIPE_BLENDFACTOR_ZERO:
> term[0] = 0.0f; /* R */
> @@ -279,10 +289,14 @@ compute_blend_ref_term(unsigned rgb_factor,
> term[2] = factor[2] * (1.0f - con[3]); /* B */
> break;
> case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
> - assert(0); /* to do */
> + term[0] = factor[0] * (1.0f - src1[0]); /* R */
> + term[1] = factor[1] * (1.0f - src1[1]); /* G */
> + term[2] = factor[2] * (1.0f - src1[2]); /* B */
> break;
> case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
> - assert(0); /* to do */
> + term[0] = factor[0] * (1.0f - src1[3]); /* R */
> + term[1] = factor[1] * (1.0f - src1[3]); /* G */
> + term[2] = factor[2] * (1.0f - src1[3]); /* B */
> break;
> default:
> assert(0);
> @@ -310,6 +324,10 @@ compute_blend_ref_term(unsigned rgb_factor,
> case PIPE_BLENDFACTOR_CONST_ALPHA:
> term[3] = factor[3] * con[3]; /* A */
> break;
> + case PIPE_BLENDFACTOR_SRC1_COLOR:
> + case PIPE_BLENDFACTOR_SRC1_ALPHA:
> + term[3] = factor[3] * src1[3]; /* A */
> + break;
> case PIPE_BLENDFACTOR_ZERO:
> term[3] = 0.0f; /* A */
> break;
> @@ -325,6 +343,10 @@ compute_blend_ref_term(unsigned rgb_factor,
> case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
> term[3] = factor[3] * (1.0f - con[3]);
> break;
> + case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
> + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
> + term[3] = factor[3] * (1.0f - src1[3]); /* A */
> + break;
> default:
> assert(0);
> }
> @@ -334,6 +356,7 @@ compute_blend_ref_term(unsigned rgb_factor,
> static void
> compute_blend_ref(const struct pipe_blend_state *blend,
> const double *src,
> + const double *src1,
> const double *dst,
> const double *con,
> double *res)
> @@ -342,9 +365,9 @@ compute_blend_ref(const struct pipe_blend_state *blend,
> double dst_term[4];
>
> compute_blend_ref_term(blend->rt[0].rgb_src_factor,
> blend->rt[0].alpha_src_factor,
> - src, src, dst, con, src_term);
> + src, src, src1, dst, con, src_term);
> compute_blend_ref_term(blend->rt[0].rgb_dst_factor,
> blend->rt[0].alpha_dst_factor,
> - dst, src, dst, con, dst_term);
> + dst, src, src1, dst, con, dst_term);
>
> /*
> * Combine RGB terms
> @@ -435,8 +458,9 @@ test_one(unsigned verbose,
> success = TRUE;
>
> {
> - uint8_t *src, *dst, *con, *res, *ref;
> + uint8_t *src, *src1, *dst, *con, *res, *ref;
> src = align_malloc(stride, stride);
> + src1 = align_malloc(stride, stride);
> dst = align_malloc(stride, stride);
> con = align_malloc(stride, stride);
> res = align_malloc(stride, stride);
> @@ -447,27 +471,30 @@ test_one(unsigned verbose,
> int64_t end_counter = 0;
>
> random_vec(type, src);
> + random_vec(type, src1);
> random_vec(type, dst);
> random_vec(type, con);
>
> {
> double fsrc[LP_MAX_VECTOR_LENGTH];
> + double fsrc1[LP_MAX_VECTOR_LENGTH];
> double fdst[LP_MAX_VECTOR_LENGTH];
> double fcon[LP_MAX_VECTOR_LENGTH];
> double fref[LP_MAX_VECTOR_LENGTH];
>
> read_vec(type, src, fsrc);
> + read_vec(type, src1, fsrc1);
> read_vec(type, dst, fdst);
> read_vec(type, con, fcon);
>
> for(j = 0; j < type.length; j += 4)
> - compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref +
> j);
> + compute_blend_ref(blend, fsrc + j, fsrc1 + j, fdst + j, fcon
> + j, fref + j);
>
> write_vec(type, ref, fref);
> }
>
> start_counter = rdtsc();
> - blend_test_ptr(src, dst, con, res);
> + blend_test_ptr(src, src1, dst, con, res);
> end_counter = rdtsc();
>
> cycles[i] = end_counter - start_counter;
> @@ -483,6 +510,10 @@ test_one(unsigned verbose,
> dump_vec(stderr, type, src);
> fprintf(stderr, "\n");
>
> + fprintf(stderr, " Src1: ");
> + dump_vec(stderr, type, src1);
> + fprintf(stderr, "\n");
> +
> fprintf(stderr, " Dst: ");
> dump_vec(stderr, type, dst);
> fprintf(stderr, "\n");
> @@ -501,6 +532,7 @@ test_one(unsigned verbose,
> }
> }
> align_free(src);
> + align_free(src1);
> align_free(dst);
> align_free(con);
> align_free(res);
> @@ -559,10 +591,8 @@ blend_factors[] = {
> PIPE_BLENDFACTOR_DST_ALPHA,
> PIPE_BLENDFACTOR_CONST_COLOR,
> PIPE_BLENDFACTOR_CONST_ALPHA,
> -#if 0
> PIPE_BLENDFACTOR_SRC1_COLOR,
> PIPE_BLENDFACTOR_SRC1_ALPHA,
> -#endif
> PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE,
> PIPE_BLENDFACTOR_INV_SRC_COLOR,
> PIPE_BLENDFACTOR_INV_SRC_ALPHA,
> @@ -570,10 +600,8 @@ blend_factors[] = {
> PIPE_BLENDFACTOR_INV_DST_ALPHA,
> PIPE_BLENDFACTOR_INV_CONST_COLOR,
> PIPE_BLENDFACTOR_INV_CONST_ALPHA,
> -#if 0
> PIPE_BLENDFACTOR_INV_SRC1_COLOR,
> PIPE_BLENDFACTOR_INV_SRC1_ALPHA,
> -#endif
> };
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
More information about the mesa-dev
mailing list