diff options
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_swizzle.c | 40 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_swizzle.h | 6 |
2 files changed, 33 insertions, 13 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c index 3182573db2..627890a3af 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c @@ -132,6 +132,32 @@ lp_build_broadcast_aos(struct lp_build_context *bld, LLVMValueRef +lp_build_select(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b) +{ + const union lp_type type = bld->type; + + if(a == b) + return a; + + /* TODO: On SSE4 we could do this with a single instruction -- PBLENDVB */ + + a = LLVMBuildAnd(bld->builder, a, mask, ""); + + /* This often gets translated to PANDN, but sometimes the NOT is + * pre-computed and stored in another constant. The best strategy depends + * on available registers, so it is not a big deal -- hopefully LLVM does + * the right decision attending the rest of the program. + */ + b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); + + return LLVMBuildOr(bld->builder, a, b, ""); +} + + +LLVMValueRef lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b, @@ -188,19 +214,7 @@ lp_build_select_aos(struct lp_build_context *bld, #endif else { LLVMValueRef mask = lp_build_const_mask_aos(type, cond); - - /* TODO: On SSE4 we could do this with a single instruction -- PBLENDVB */ - - a = LLVMBuildAnd(bld->builder, a, mask, ""); - - /* This often gets translated to PANDN, but sometimes the NOT is - * pre-computed and stored in another constant. The best strategy depends - * on available registers, so it is not a big deal -- hopefully LLVM does - * the right decision attending the rest of the program. - */ - b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); - - return LLVMBuildOr(bld->builder, a, b, ""); + return lp_build_select(bld, mask, a, b); } } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h index dede675e58..fe53e86786 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h @@ -60,6 +60,12 @@ lp_build_broadcast_aos(struct lp_build_context *bld, LLVMValueRef +lp_build_select(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b); + +LLVMValueRef lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b, |