From af608e56ca246232ef11a561040b84801ae3a552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 14 Aug 2009 10:03:12 +0100 Subject: [PATCH] llvmpipe: Factor out lp_build_select from lp_build_select_aos. --- src/gallium/drivers/llvmpipe/lp_bld_swizzle.c | 40 +++++++++++++------ 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 @@ -131,6 +131,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, @@ -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 @@ -59,6 +59,12 @@ lp_build_broadcast_aos(struct lp_build_context *bld, unsigned channel); +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,