summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2009-08-14 10:03:12 +0100
committerJosé Fonseca <[email protected]>2009-08-29 09:21:31 +0100
commitaf608e56ca246232ef11a561040b84801ae3a552 (patch)
treee9f55ec30d8a6721dec3d9e8c016e7010e8303b3
parent57907e7fd9fc63b9023d0e2b08934c2d0acf2953 (diff)
llvmpipe: Factor out lp_build_select from lp_build_select_aos.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.c40
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.h6
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,