#define LP_BLD_TYPE_H
+#include "util/u_format.h"
#include "pipe/p_compiler.h"
#include "gallivm/lp_bld.h"
+/**
+ * Native SIMD architecture width available at runtime.
+ *
+ * Using this width should give the best performance,
+ * and it determines the necessary alignment of vector variables.
+ */
+extern unsigned lp_native_vector_width;
+/**
+ * Maximum supported vector width (not necessarily supported at run-time).
+ *
+ * Should only be used when lp_native_vector_width isn't available,
+ * i.e. sizing/alignment of non-malloced variables.
+ */
+#define LP_MAX_VECTOR_WIDTH 256
/**
- * Native SIMD register width.
+ * Minimum vector alignment for static variable alignment
*
- * 128 for all architectures we care about.
+ * It should always be a constant equal to LP_MAX_VECTOR_WIDTH/8. An
+ * expression is non-portable.
*/
-#define LP_NATIVE_VECTOR_WIDTH 128
+#define LP_MIN_VECTOR_ALIGN 32
/**
* Several functions can only cope with vectors of length up to this value.
* You may need to increase that value if you want to represent bigger vectors.
*/
-#define LP_MAX_VECTOR_LENGTH 16
-
+#define LP_MAX_VECTOR_LENGTH (LP_MAX_VECTOR_WIDTH/8)
/**
* The LLVM type system can't conveniently express all the things we care about
*/
struct lp_build_context
{
- LLVMBuilderRef builder;
+ struct gallivm_state *gallivm;
/**
* This not only describes the input/output LLVM types, but also whether
};
+/**
+ * Converts a format description into an lp_type.
+ *
+ * Only works with "array formats".
+ *
+ * e.g. With PIPE_FORMAT_R32G32B32A32_FLOAT returns an lp_type with float[4]
+ */
+static INLINE void
+lp_type_from_format_desc(struct lp_type* type, const struct util_format_description *format_desc)
+{
+ assert(format_desc->is_array);
+ assert(!format_desc->is_mixed);
+
+ memset(type, 0, sizeof(struct lp_type));
+ type->floating = format_desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT;
+ type->fixed = format_desc->channel[0].type == UTIL_FORMAT_TYPE_FIXED;
+ type->sign = format_desc->channel[0].type != UTIL_FORMAT_TYPE_UNSIGNED;
+ type->norm = format_desc->channel[0].normalized;
+ type->width = format_desc->channel[0].size;
+ type->length = format_desc->nr_channels;
+}
+
+
+static INLINE void
+lp_type_from_format(struct lp_type* type, enum pipe_format format)
+{
+ lp_type_from_format_desc(type, util_format_description(format));
+}
+
+
+static INLINE unsigned
+lp_type_width(struct lp_type type)
+{
+ return type.width * type.length;
+}
+
+
/** Create scalar float type */
static INLINE struct lp_type
lp_type_float(unsigned width)
/** Create vector of float type */
static INLINE struct lp_type
-lp_type_float_vec(unsigned width)
+lp_type_float_vec(unsigned width, unsigned total_width)
{
struct lp_type res_type;
res_type.floating = TRUE;
res_type.sign = TRUE;
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
/** Create vector int type */
static INLINE struct lp_type
-lp_type_int_vec(unsigned width)
+lp_type_int_vec(unsigned width, unsigned total_width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.sign = TRUE;
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
/** Create vector uint type */
static INLINE struct lp_type
-lp_type_uint_vec(unsigned width)
+lp_type_uint_vec(unsigned width, unsigned total_width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
static INLINE struct lp_type
-lp_type_unorm(unsigned width)
+lp_type_unorm(unsigned width, unsigned total_width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.norm = TRUE;
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
static INLINE struct lp_type
-lp_type_fixed(unsigned width)
+lp_type_fixed(unsigned width, unsigned total_width)
{
struct lp_type res_type;
res_type.sign = TRUE;
res_type.fixed = TRUE;
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
static INLINE struct lp_type
-lp_type_ufixed(unsigned width)
+lp_type_ufixed(unsigned width, unsigned total_width)
{
struct lp_type res_type;
memset(&res_type, 0, sizeof res_type);
res_type.fixed = TRUE;
res_type.width = width;
- res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
+ res_type.length = total_width / width;
return res_type;
}
LLVMTypeRef
-lp_build_elem_type(struct lp_type type);
+lp_build_elem_type(struct gallivm_state *gallivm, struct lp_type type);
LLVMTypeRef
-lp_build_vec_type(struct lp_type type);
+lp_build_vec_type(struct gallivm_state *gallivm, struct lp_type type);
boolean
LLVMTypeRef
-lp_build_int_elem_type(struct lp_type type);
-
-
-LLVMTypeRef
-lp_build_int_vec_type(struct lp_type type);
+lp_build_int_elem_type(struct gallivm_state *gallivm, struct lp_type type);
LLVMTypeRef
-lp_build_int32_vec4_type(void);
+lp_build_int_vec_type(struct gallivm_state *gallivm, struct lp_type type);
static INLINE struct lp_type
void
lp_build_context_init(struct lp_build_context *bld,
- LLVMBuilderRef builder,
+ struct gallivm_state *gallivm,
struct lp_type type);
+unsigned
+lp_build_count_ir_module(LLVMModuleRef module);
+
+
#endif /* !LP_BLD_TYPE_H */