summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.c125
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.h25
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.c19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.h8
5 files changed, 141 insertions, 40 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/drivers/llvmpipe/lp_bld_const.c
index fe1c627eee..d36a610234 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_const.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.c
@@ -40,6 +40,56 @@
#include "lp_bld_const.h"
+/**
+ * Shift of the unity.
+ *
+ * Same as lp_const_scale(), but in terms of shifts.
+ */
+unsigned
+lp_const_shift(union lp_type type)
+{
+ if(type.fixed)
+ return type.width/2;
+ else if(type.norm)
+ return type.sign ? type.width - 1 : type.width;
+ else
+ return 0;
+}
+
+
+static unsigned
+lp_const_offset(union lp_type type)
+{
+ if(type.floating || type.fixed)
+ return 0;
+ else if(type.norm)
+ return 1;
+ else
+ return 0;
+}
+
+
+/**
+ * Scaling factor between the LLVM native value and its interpretation.
+ *
+ * This is 1.0 for all floating types and unnormalized integers, and something
+ * else for the fixed points types and normalized integers.
+ */
+double
+lp_const_scale(union lp_type type)
+{
+ unsigned long long llscale;
+ double dscale;
+
+ llscale = (unsigned long long)1 << lp_const_shift(type);
+ llscale -= lp_const_offset(type);
+ dscale = (double)llscale;
+ assert((unsigned long long)dscale == llscale);
+
+ return dscale;
+}
+
+
LLVMValueRef
lp_build_undef(union lp_type type)
{
@@ -93,6 +143,49 @@ lp_build_one(union lp_type type)
LLVMValueRef
+lp_build_const_uni(union lp_type type,
+ double val)
+{
+ LLVMTypeRef elem_type = lp_build_elem_type(type);
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ if(type.floating) {
+ elems[0] = LLVMConstReal(elem_type, val);
+ }
+ else {
+ double dscale = lp_const_scale(type);
+
+ elems[0] = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
+ }
+
+ for(i = 1; i < type.length; ++i)
+ elems[i] = elems[0];
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
+lp_build_int_const_uni(union lp_type type,
+ long long val)
+{
+ LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ for(i = 0; i < type.length; ++i)
+ elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0);
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
lp_build_const_aos(union lp_type type,
double r, double g, double b, double a,
const unsigned char *swizzle)
@@ -117,20 +210,7 @@ lp_build_const_aos(union lp_type type,
elems[swizzle[3]] = LLVMConstReal(elem_type, a);
}
else {
- unsigned shift;
- long long llscale;
- double dscale;
-
- if(type.fixed)
- shift = type.width/2;
- else if(type.norm)
- shift = type.sign ? type.width - 1 : type.width;
- else
- shift = 0;
-
- llscale = (long long)1 << shift;
- dscale = (double)llscale;
- assert((long long)dscale == llscale);
+ double dscale = lp_const_scale(type);
elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0);
elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0);
@@ -146,23 +226,6 @@ lp_build_const_aos(union lp_type type,
LLVMValueRef
-lp_build_const_shift(union lp_type type,
- int c)
-{
- LLVMTypeRef elem_type = LLVMIntType(type.width);
- LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
- unsigned i;
-
- assert(type.length <= LP_MAX_VECTOR_LENGTH);
-
- for(i = 0; i < type.length; ++i)
- elems[i] = LLVMConstInt(elem_type, c, 0);
-
- return LLVMConstVector(elems, type.length);
-}
-
-
-LLVMValueRef
lp_build_const_mask_aos(union lp_type type,
boolean cond[4])
{
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/drivers/llvmpipe/lp_bld_const.h
index 98ed8911a5..ed6b185fce 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_const.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.h
@@ -39,10 +39,20 @@
#include <llvm-c/Core.h>
+#include <pipe/p_compiler.h>
+
union lp_type type;
+unsigned
+lp_const_shift(union lp_type type);
+
+
+double
+lp_const_scale(union lp_type type);
+
+
LLVMValueRef
lp_build_undef(union lp_type type);
@@ -56,14 +66,19 @@ lp_build_one(union lp_type type);
LLVMValueRef
-lp_build_const_aos(union lp_type type,
- double r, double g, double b, double a,
- const unsigned char *swizzle);
+lp_build_const_uni(union lp_type type,
+ double val);
+
+
+LLVMValueRef
+lp_build_int_const_uni(union lp_type type,
+ long long val);
LLVMValueRef
-lp_build_const_shift(union lp_type type,
- int c);
+lp_build_const_aos(union lp_type type,
+ double r, double g, double b, double a,
+ const unsigned char *swizzle);
LLVMValueRef
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
index 8cda4a48ba..1f83bf6782 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
@@ -99,9 +99,9 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
#endif
if(shift > 0)
- tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_shift(type4, shift*type.width), "");
+ tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_uni(type4, shift*type.width), "");
if(shift < 0)
- tmp = LLVMBuildShl(bld->builder, a, lp_build_const_shift(type4, -shift*type.width), "");
+ tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_uni(type4, -shift*type.width), "");
assert(tmp);
if(tmp)
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.c b/src/gallium/drivers/llvmpipe/lp_bld_type.c
index e2abd04f60..1e95a1a349 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_type.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.c
@@ -37,7 +37,7 @@ lp_build_elem_type(union lp_type type)
if (type.floating) {
assert(type.sign);
switch(type.width) {
- case 32:
+ case 32:
return LLVMFloatType();
break;
case 64:
@@ -63,7 +63,7 @@ lp_build_vec_type(union lp_type type)
/**
- * This function is a mirrot of lp_build_elem_type() above.
+ * This function is a mirror of lp_build_elem_type() above.
*
* XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
* type and check for identity.
@@ -140,3 +140,18 @@ lp_check_value(union lp_type type, LLVMValueRef val)
return lp_check_vec_type(type, vec_type);
}
+
+
+LLVMTypeRef
+lp_build_int_elem_type(union lp_type type)
+{
+ return LLVMIntType(type.width);
+}
+
+
+LLVMTypeRef
+lp_build_int_vec_type(union lp_type type)
+{
+ LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+ return LLVMVectorType(elem_type, type.length);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.h b/src/gallium/drivers/llvmpipe/lp_bld_type.h
index 0eeaf7b6aa..566a86ed06 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_type.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.h
@@ -154,4 +154,12 @@ boolean
lp_check_value(union lp_type type, LLVMValueRef val);
+LLVMTypeRef
+lp_build_int_elem_type(union lp_type type);
+
+
+LLVMTypeRef
+lp_build_int_vec_type(union lp_type type);
+
+
#endif /* !LP_BLD_TYPE_H */