diff options
author | José Fonseca <[email protected]> | 2009-08-14 10:03:12 +0100 |
---|---|---|
committer | José Fonseca <[email protected]> | 2009-08-29 09:21:31 +0100 |
commit | af608e56ca246232ef11a561040b84801ae3a552 (patch) | |
tree | e9f55ec30d8a6721dec3d9e8c016e7010e8303b3 | |
parent | 57907e7fd9fc63b9023d0e2b08934c2d0acf2953 (diff) |
llvmpipe: Factor out lp_build_select from lp_build_select_aos.
-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 3182573db29..627890a3af1 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 dede675e588..fe53e86786d 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, |