gallivm: Fix format manipulation for big-endian
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_format_aos.c
index 9591bcfb2c75c402f399aef320d33c780d125424..750d54524c6f95908deb0cf083d26ceadeabbdb9 100644 (file)
@@ -49,6 +49,7 @@
 #include "lp_bld_gather.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_format.h"
+#include "lp_bld_intr.h"
 
 
 /**
@@ -171,6 +172,10 @@ lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm,
     * matches floating point size */
    assert (LLVMTypeOf(packed) == LLVMInt32TypeInContext(gallivm->context));
 
+#ifdef PIPE_ARCH_BIG_ENDIAN
+   packed = lp_build_bswap(gallivm, packed, lp_type_uint(32));
+#endif
+
    /* Broadcast the packed value to all four channels
     * before: packed = BGRA
     * after: packed = {BGRA, BGRA, BGRA, BGRA}
@@ -396,6 +401,8 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
        format_desc->block.bits <= type.width * 4 &&
        util_is_power_of_two(format_desc->block.bits)) {
       LLVMValueRef packed;
+      LLVMTypeRef dst_vec_type = lp_build_vec_type(gallivm, type);
+      unsigned vec_len = type.width * type.length;
 
       /*
        * The format matches the type (apart of a swizzle) so no need for
@@ -406,11 +413,14 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
                                format_desc->block.bits, type.width*4,
                                base_ptr, offset);
 
-      assert(format_desc->block.bits <= type.width * type.length);
-
-      packed = LLVMBuildBitCast(gallivm->builder, packed,
-                                lp_build_vec_type(gallivm, type), "");
+      assert(format_desc->block.bits <= vec_len);
 
+      packed = LLVMBuildBitCast(gallivm->builder, packed, dst_vec_type, "");
+#ifdef PIPE_ARCH_BIG_ENDIAN
+      if (type.floating)
+         packed = lp_build_bswap_vec(gallivm, packed, type,
+                                    lp_type_float_vec(type.width, vec_len));
+#endif
       return lp_build_format_swizzle_aos(format_desc, &bld, packed);
    }