util: Move gallium's PIPE_FORMAT utils to /util/format/
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_type.h
index 4daa904e633c8e73457236e190c48c1964c5a6e9..9c7dc252166d8e693f7abf633317a24c390a21dc 100644 (file)
 #define LP_BLD_TYPE_H
 
 
-#include <llvm-c/Core.h>  
+#include "util/format/u_format.h"
+#include "pipe/p_compiler.h"
+#include "gallivm/lp_bld.h"
 
-#include <pipe/p_compiler.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+/**
+ * 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 512
 
 /**
- * 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 64
 
 /**
  * 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
@@ -120,7 +139,7 @@ struct lp_type {
  */
 struct lp_build_context
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
 
    /**
     * This not only describes the input/output LLVM types, but also whether
@@ -128,6 +147,18 @@ struct lp_build_context
     */
    struct lp_type type;
 
+   /** Same as lp_build_elem_type(type) */
+   LLVMTypeRef elem_type;
+
+   /** Same as lp_build_vec_type(type) */
+   LLVMTypeRef vec_type;
+
+   /** Same as lp_build_int_elem_type(type) */
+   LLVMTypeRef int_elem_type;
+
+   /** Same as lp_build_int_vec_type(type) */
+   LLVMTypeRef int_vec_type;
+
    /** Same as lp_build_undef(type) */
    LLVMValueRef undef;
 
@@ -139,8 +170,45 @@ struct lp_build_context
 };
 
 
+/**
+ * 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
+static inline struct lp_type
 lp_type_float(unsigned width)
 {
    struct lp_type res_type;
@@ -156,8 +224,8 @@ lp_type_float(unsigned width)
 
 
 /** Create vector of float type */
-static INLINE struct lp_type
-lp_type_float_vec(unsigned width)
+static inline struct lp_type
+lp_type_float_vec(unsigned width, unsigned total_width)
 {
    struct lp_type res_type;
 
@@ -165,14 +233,14 @@ lp_type_float_vec(unsigned width)
    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 scalar int type */
-static INLINE struct lp_type
+static inline struct lp_type
 lp_type_int(unsigned width)
 {
    struct lp_type res_type;
@@ -187,22 +255,22 @@ lp_type_int(unsigned width)
 
 
 /** Create vector int type */
-static INLINE struct lp_type
-lp_type_int_vec(unsigned width)
+static inline struct lp_type
+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 scalar uint type */
-static INLINE struct lp_type
+static inline struct lp_type
 lp_type_uint(unsigned width)
 {
    struct lp_type res_type;
@@ -216,35 +284,35 @@ lp_type_uint(unsigned width)
 
 
 /** Create vector uint type */
-static INLINE struct lp_type
-lp_type_uint_vec(unsigned width)
+static inline struct lp_type
+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)
+static inline struct lp_type
+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)
+static inline struct lp_type
+lp_type_fixed(unsigned width, unsigned total_width)
 {
    struct lp_type res_type;
 
@@ -252,32 +320,32 @@ lp_type_fixed(unsigned width)
    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)
+static inline struct lp_type
+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
@@ -293,15 +361,63 @@ lp_check_value(struct lp_type type, LLVMValueRef val);
 
 
 LLVMTypeRef
-lp_build_int_elem_type(struct lp_type type);
+lp_build_int_elem_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
 LLVMTypeRef
-lp_build_int_vec_type(struct lp_type type);
+lp_build_int_vec_type(struct gallivm_state *gallivm, struct lp_type type);
 
 
-LLVMTypeRef
-lp_build_int32_vec4_type(void);
+static inline struct lp_type
+lp_float32_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = TRUE;
+   type.sign = TRUE;
+   type.norm = FALSE;
+   type.width = 32;
+   type.length = 4;
+
+   return type;
+}
+
+
+static inline struct lp_type
+lp_int32_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = FALSE;
+   type.sign = TRUE;
+   type.norm = FALSE;
+   type.width = 32;
+   type.length = 4;
+
+   return type;
+}
+
+
+static inline struct lp_type
+lp_unorm8_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = FALSE;
+   type.sign = FALSE;
+   type.norm = TRUE;
+   type.width = 8;
+   type.length = 4;
+
+   return type;
+}
+
+
+struct lp_type
+lp_elem_type(struct lp_type type);
 
 
 struct lp_type
@@ -316,10 +432,29 @@ struct lp_type
 lp_wider_type(struct lp_type type);
 
 
+unsigned
+lp_sizeof_llvm_type(LLVMTypeRef t);
+
+
+const char *
+lp_typekind_name(LLVMTypeKind t);
+
+
+void
+lp_dump_llvmtype(LLVMTypeRef t);
+
+
 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);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* !LP_BLD_TYPE_H */