summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
diff options
context:
space:
mode:
authorAdam Jackson <[email protected]>2013-06-24 09:48:56 -0400
committerAdam Jackson <[email protected]>2013-06-24 09:48:56 -0400
commit2151d893fbd4a4be092098170e2fbca8c35797a5 (patch)
tree88af00d0b64d08bf04d33f972709db32aecf884d /src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
parentd282f4ea9b99e4eefec8ce0664cdf49d53d7b052 (diff)
gallium: Fix llvmpipe on big-endian machines
Squashed commit of the following: commit 0857a7e105bfcbc4d1431b2cc56612094c747ca3 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:07 2013 -0400 gallivm: Fix lp_build_rgba8_to_fi32_soa for big endian Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 0d65131649a8aa140e2db228ba779d685c4333e3 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:07 2013 -0400 gallivm: Fix big-endian machines This adds a bit-shift count to the format table, and adds the concept of vector or bitwise alignment on gathers. Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 9740bda9b7dc894b629ed38be9b51059ce90818f Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:07 2013 -0400 llvmpipe: Fix convert_to_blend_type on big-endian Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit ae037c2de0f029e4e99371c0de25560484f0d8df Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 util: Convert color pack to packed formats This fixes them on big-endian. Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 5b05ac0c89ae092ea8ba5bba9f739708d7396b5c Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 graw-xlib: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 51396e7d098cb6ff794391cf11afe4dbf86dbea0 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 format: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 417b60bc66eb450e68a92ab0e47f76e292b385e6 Author: Adam Jackson <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 st/dri: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 0934b2e022a5e0847d312c40734e2b44cac52fd8 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 st/xlib: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit a307ea3c3716a706963acce7966b5e405ba11db9 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 gbm: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 53eebdd253e1960a645ea278f31d7ef6a6cf4aeb Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 tests: Convert to packed formats Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 2f77fe3ee524945eacd546efcac34f7799fb3124 Author: Adam Jackson <[email protected]> Date: Tue Jun 18 13:07:37 2013 -0400 gallium: Document packed formats Signed-off-by: Adam Jackson <[email protected]> commit 1f1017159ce951f922210a430de9229f91f62714 Author: Richard Sandiford <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 gallium: Introduce 32-bit packed format names These are for interacting with buffers natively described in terms of bit shifts, like X11 visuals: uint32_t xyzw8888 = (x << 0) | (y << 8) | (z << 16) | (w << 24); Define these in terms of (endian-dependent) aliases to the array-style format names. Reviewed-by: Adam Jackson <[email protected]> Signed-off-by: Richard Sandiford <[email protected]> commit 6cc7ab1ee66ed668da78c1d951dfd7782b4e786a Author: Adam Jackson <[email protected]> Date: Mon Jun 3 12:10:32 2013 -0400 gallium: Document format name conventions v2: - Fix a channel name thinko (Michel Dänzer) - Elaborate on SCALED versus INT - Add links to DirectX and FOURCC docs Signed-off-by: Adam Jackson <[email protected]> commit df4d269e7fb62051a3c029b84147465001e5776e Author: Adam Jackson <[email protected]> Date: Tue Jun 18 12:25:06 2013 -0400 gallivm: Remove all notion of byte-swapping Signed-off-by: Adam Jackson <[email protected]> Signed-off-by: Adam Jackson <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_swizzle.c')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
index 08d817a28f5..79116bcf391 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
@@ -217,6 +217,20 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type2), "");
+ /*
+ * Vector element 0 is always channel X.
+ *
+ * 76 54 32 10 (array numbering)
+ * Little endian reg in: YX YX YX YX
+ * Little endian reg out: YY YY YY YY if shift right (shift == -1)
+ * XX XX XX XX if shift left (shift == 1)
+ *
+ * 01 23 45 67 (array numbering)
+ * Big endian reg in: XY XY XY XY
+ * Big endian reg out: YY YY YY YY if shift left (shift == 1)
+ * XX XX XX XX if shift right (shift == -1)
+ *
+ */
#ifdef PIPE_ARCH_LITTLE_ENDIAN
shift = channel == 0 ? 1 : -1;
#else
@@ -240,10 +254,23 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
/*
* Bit mask and recursive shifts
*
+ * Little-endian registers:
+ *
+ * 7654 3210
+ * WZYX WZYX .... WZYX <= input
+ * 00Y0 00Y0 .... 00Y0 <= mask
+ * 00YY 00YY .... 00YY <= shift right 1 (shift amount -1)
+ * YYYY YYYY .... YYYY <= shift left 2 (shift amount 2)
+ *
+ * Big-endian registers:
+ *
+ * 0123 4567
* XYZW XYZW .... XYZW <= input
- * 0Y00 0Y00 .... 0Y00
- * YY00 YY00 .... YY00
- * YYYY YYYY .... YYYY <= output
+ * 0Y00 0Y00 .... 0Y00 <= mask
+ * YY00 YY00 .... YY00 <= shift left 1 (shift amount 1)
+ * YYYY YYYY .... YYYY <= shift right 2 (shift amount -2)
+ *
+ * shifts[] gives little-endian shift amounts; we need to negate for big-endian.
*/
struct lp_type type4;
const int shifts[4][2] = {
@@ -274,14 +301,15 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
LLVMValueRef tmp = NULL;
int shift = shifts[channel][i];
-#ifdef PIPE_ARCH_LITTLE_ENDIAN
+ /* See endianness diagram above */
+#ifdef PIPE_ARCH_BIG_ENDIAN
shift = -shift;
#endif
if(shift > 0)
- tmp = LLVMBuildLShr(builder, a, lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
+ tmp = LLVMBuildShl(builder, a, lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
if(shift < 0)
- tmp = LLVMBuildShl(builder, a, lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
+ tmp = LLVMBuildLShr(builder, a, lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
assert(tmp);
if(tmp)
@@ -474,21 +502,39 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
/*
* Mask and shift the channels, trying to group as many channels in the
- * same shift as possible
+ * same shift as possible. The shift amount is positive for shifts left
+ * and negative for shifts right.
*/
for (shift = -3; shift <= 3; ++shift) {
uint64_t mask = 0;
assert(type4.width <= sizeof(mask)*8);
+ /*
+ * Vector element numbers follow the XYZW order, so 0 is always X, etc.
+ * After widening 4 times we have:
+ *
+ * 3210
+ * Little-endian register layout: WZYX
+ *
+ * 0123
+ * Big-endian register layout: XYZW
+ *
+ * For little-endian, higher-numbered channels are obtained by a shift right
+ * (negative shift amount) and lower-numbered channels by a shift left
+ * (positive shift amount). The opposite is true for big-endian.
+ */
for (chan = 0; chan < 4; ++chan) {
- /* FIXME: big endian */
- if (swizzles[chan] < 4 &&
- chan - swizzles[chan] == shift) {
+ if (swizzles[chan] < 4) {
+ /* We need to move channel swizzles[chan] into channel chan */
#ifdef PIPE_ARCH_LITTLE_ENDIAN
- mask |= ((1ULL << type.width) - 1) << (swizzles[chan] * type.width);
+ if (swizzles[chan] - chan == -shift) {
+ mask |= ((1ULL << type.width) - 1) << (swizzles[chan] * type.width);
+ }
#else
- mask |= ((1ULL << type.width) - 1) << (type4.width - type.width) >> (swizzles[chan] * type.width);
+ if (swizzles[chan] - chan == shift) {
+ mask |= ((1ULL << type.width) - 1) << (type4.width - type.width) >> (swizzles[chan] * type.width);
+ }
#endif
}
}
@@ -502,21 +548,11 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
masked = LLVMBuildAnd(builder, a,
lp_build_const_int_vec(bld->gallivm, type4, mask), "");
if (shift > 0) {
-#ifdef PIPE_ARCH_LITTLE_ENDIAN
shifted = LLVMBuildShl(builder, masked,
lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
-#else
- shifted = LLVMBuildLShr(builder, masked,
- lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
-#endif
} else if (shift < 0) {
-#ifdef PIPE_ARCH_LITTLE_ENDIAN
shifted = LLVMBuildLShr(builder, masked,
lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
-#else
- shifted = LLVMBuildShl(builder, masked,
- lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
-#endif
} else {
shifted = masked;
}