gallivm/nir: allow 64-bit arit ops
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_format_aos.c
index 2f723857f4b7d2916b9a52626d41a776342de5a5..74fe1672b27f8ec9fcd392ef59478972a365747a 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_pointer.h"
@@ -54,7 +54,7 @@
 #include "lp_bld_intr.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_bitarit.h"
-
+#include "lp_bld_misc.h"
 
 /**
  * Basic swizzling.  Rearrange the order of the unswizzled array elements
@@ -464,6 +464,7 @@ lp_build_pack_rgba_aos(struct gallivm_state *gallivm,
  * \param ptr  address of the pixel block (or the texel if uncompressed)
  * \param i, j  the sub-block pixel coordinates.  For non-compressed formats
  *              these will always be (0, 0).
+ * \param cache  optional value pointing to a lp_build_format_cache structure
  * \return  a 4 element vector with the pixel's RGBA values.
  */
 LLVMValueRef
@@ -477,6 +478,8 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
                         LLVMValueRef j,
                         LLVMValueRef cache)
 {
+   const struct util_format_unpack_description *unpack =
+      util_format_unpack_description(format_desc->format);
    LLVMBuilderRef builder = gallivm->builder;
    unsigned num_pixels = type.length / 4;
    struct lp_build_context bld;
@@ -496,7 +499,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
    if (format_matches_type(format_desc, type) &&
        format_desc->block.bits <= type.width * 4 &&
        /* XXX this shouldn't be needed */
-       util_is_power_of_two(format_desc->block.bits)) {
+       util_is_power_of_two_or_zero(format_desc->block.bits)) {
       LLVMValueRef packed;
       LLVMTypeRef dst_vec_type = lp_build_vec_type(gallivm, type);
       struct lp_type fetch_type;
@@ -532,7 +535,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
        util_format_fits_8unorm(format_desc) &&
        type.width == 8 && type.norm == 1 && type.sign == 0 &&
        type.fixed == 0 && type.floating == 0) {
-      LLVMValueRef packed, res, chans[4], rgba[4];
+      LLVMValueRef packed, res = NULL, chans[4], rgba[4];
       LLVMTypeRef dst_vec_type, conv_vec_type;
       struct lp_type fetch_type, conv_type;
       struct lp_build_context bld_conv;
@@ -609,7 +612,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
        format_desc->block.width == 1 &&
        format_desc->block.height == 1 &&
        /* XXX this shouldn't be needed */
-       util_is_power_of_two(format_desc->block.bits) &&
+       util_is_power_of_two_or_zero(format_desc->block.bits) &&
        format_desc->block.bits <= 32 &&
        format_desc->is_bitmask &&
        !format_desc->is_mixed &&
@@ -728,7 +731,35 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
     * s3tc rgb formats
     */
 
-   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC && cache) {
+   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+      struct lp_type tmp_type;
+      LLVMValueRef tmp;
+
+      memset(&tmp_type, 0, sizeof tmp_type);
+      tmp_type.width = 8;
+      tmp_type.length = num_pixels * 4;
+      tmp_type.norm = TRUE;
+
+      tmp = lp_build_fetch_s3tc_rgba_aos(gallivm,
+                                         format_desc,
+                                         num_pixels,
+                                         base_ptr,
+                                         offset,
+                                         i, j,
+                                         cache);
+
+      lp_build_conv(gallivm,
+                    tmp_type, type,
+                    &tmp, 1, &tmp, 1);
+
+       return tmp;
+   }
+
+   /*
+    * rgtc rgb formats
+    */
+
+   if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
       struct lp_type tmp_type;
       LLVMValueRef tmp;
 
@@ -736,8 +767,12 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
       tmp_type.width = 8;
       tmp_type.length = num_pixels * 4;
       tmp_type.norm = TRUE;
+      tmp_type.sign = (format_desc->format == PIPE_FORMAT_RGTC1_SNORM ||
+                       format_desc->format == PIPE_FORMAT_RGTC2_SNORM ||
+                       format_desc->format == PIPE_FORMAT_LATC1_SNORM ||
+                       format_desc->format == PIPE_FORMAT_LATC2_SNORM);
 
-      tmp = lp_build_fetch_cached_texels(gallivm,
+      tmp = lp_build_fetch_rgtc_rgba_aos(gallivm,
                                          format_desc,
                                          num_pixels,
                                          base_ptr,
@@ -756,7 +791,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
     * Fallback to util_format_description::fetch_rgba_8unorm().
     */
 
-   if (format_desc->fetch_rgba_8unorm &&
+   if (unpack->fetch_rgba_8unorm &&
        !type.floating && type.width == 8 && !type.sign && type.norm) {
       /*
        * Fallback to calling util_format_description::fetch_rgba_8unorm.
@@ -802,9 +837,11 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
          function_type = LLVMFunctionType(ret_type, arg_types,
                                           ARRAY_SIZE(arg_types), 0);
 
+         if (gallivm->cache)
+            gallivm->cache->dont_cache = true;
          /* make const pointer for the C fetch_rgba_8unorm function */
          function = lp_build_const_int_pointer(gallivm,
-            func_to_pointer((func_pointer) format_desc->fetch_rgba_8unorm));
+            func_to_pointer((func_pointer) unpack->fetch_rgba_8unorm));
 
          /* cast the callee pointer to the function's type */
          function = LLVMBuildBitCast(builder, function,
@@ -857,10 +894,12 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
    }
 
    /*
-    * Fallback to util_format_description::fetch_rgba_float().
+    * Fallback to fetch_rgba().
     */
 
-   if (format_desc->fetch_rgba_float) {
+   util_format_fetch_rgba_func_ptr fetch_rgba =
+      util_format_fetch_rgba_func(format_desc->format);
+   if (fetch_rgba) {
       /*
        * Fallback to calling util_format_description::fetch_rgba_float.
        *
@@ -887,7 +926,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
       }
 
       /*
-       * Declare and bind format_desc->fetch_rgba_float().
+       * Declare and bind unpack->fetch_rgba_float().
        */
 
       {
@@ -904,8 +943,10 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
          arg_types[2] = i32t;
          arg_types[3] = i32t;
 
+         if (gallivm->cache)
+            gallivm->cache->dont_cache = true;
          function = lp_build_const_func_pointer(gallivm,
-                                                func_to_pointer((func_pointer) format_desc->fetch_rgba_float),
+                                                func_to_pointer((func_pointer) fetch_rgba),
                                                 ret_type,
                                                 arg_types, ARRAY_SIZE(arg_types),
                                                 format_desc->short_name);