diff options
author | Adam Jackson <ajax@redhat.com> | 2013-06-24 09:48:56 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2013-06-24 09:48:56 -0400 |
commit | 2151d893fbd4a4be092098170e2fbca8c35797a5 (patch) | |
tree | 88af00d0b64d08bf04d33f972709db32aecf884d /src/gallium | |
parent | d282f4ea9b99e4eefec8ce0664cdf49d53d7b052 (diff) | |
download | external_mesa3d-2151d893fbd4a4be092098170e2fbca8c35797a5.zip external_mesa3d-2151d893fbd4a4be092098170e2fbca8c35797a5.tar.gz external_mesa3d-2151d893fbd4a4be092098170e2fbca8c35797a5.tar.bz2 |
gallium: Fix llvmpipe on big-endian machines
Squashed commit of the following:
commit 0857a7e105bfcbc4d1431b2cc56612094c747ca3
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:07 2013 -0400
gallivm: Fix lp_build_rgba8_to_fi32_soa for big endian
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 0d65131649a8aa140e2db228ba779d685c4333e3
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
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 <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 9740bda9b7dc894b629ed38be9b51059ce90818f
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:07 2013 -0400
llvmpipe: Fix convert_to_blend_type on big-endian
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit ae037c2de0f029e4e99371c0de25560484f0d8df
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
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 <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 5b05ac0c89ae092ea8ba5bba9f739708d7396b5c
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:06 2013 -0400
graw-xlib: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 51396e7d098cb6ff794391cf11afe4dbf86dbea0
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:06 2013 -0400
format: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 417b60bc66eb450e68a92ab0e47f76e292b385e6
Author: Adam Jackson <ajax@redhat.com>
Date: Tue Jun 18 12:25:06 2013 -0400
st/dri: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 0934b2e022a5e0847d312c40734e2b44cac52fd8
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:06 2013 -0400
st/xlib: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit a307ea3c3716a706963acce7966b5e405ba11db9
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:06 2013 -0400
gbm: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 53eebdd253e1960a645ea278f31d7ef6a6cf4aeb
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
Date: Tue Jun 18 12:25:06 2013 -0400
tests: Convert to packed formats
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 2f77fe3ee524945eacd546efcac34f7799fb3124
Author: Adam Jackson <ajax@redhat.com>
Date: Tue Jun 18 13:07:37 2013 -0400
gallium: Document packed formats
Signed-off-by: Adam Jackson <ajax@redhat.com>
commit 1f1017159ce951f922210a430de9229f91f62714
Author: Richard Sandiford <r.sandiford@uk.ibm.com>
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 <ajax@redhat.com>
Signed-off-by: Richard Sandiford <r.sandiford@uk.ibm.com>
commit 6cc7ab1ee66ed668da78c1d951dfd7782b4e786a
Author: Adam Jackson <ajax@redhat.com>
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 <ajax@redhat.com>
commit df4d269e7fb62051a3c029b84147465001e5776e
Author: Adam Jackson <ajax@redhat.com>
Date: Tue Jun 18 12:25:06 2013 -0400
gallivm: Remove all notion of byte-swapping
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'src/gallium')
31 files changed, 297 insertions, 317 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c index f11361a..cbea966 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c @@ -80,82 +80,6 @@ /** - * Byte swap on element. It will construct a call to intrinsic llvm.bswap - * based on the type. - * - * @param res element to byte swap. - * @param type int16_t, int32_t, int64_t, float or double - * @param - */ -LLVMValueRef -lp_build_bswap(struct gallivm_state *gallivm, - LLVMValueRef res, - struct lp_type type) -{ - LLVMTypeRef int_type = LLVMIntTypeInContext(gallivm->context, - type.width); - const char *intrinsic = NULL; - if (type.width == 8) - return res; - if (type.width == 16) - intrinsic = "llvm.bswap.i16"; - else if (type.width == 32) - intrinsic = "llvm.bswap.i32"; - else if (type.width == 64) - intrinsic = "llvm.bswap.i64"; - - assert (intrinsic != NULL); - - /* In case of a floating-point type cast to a int of same size and then - * cast back to fp type. - */ - if (type.floating) - res = LLVMBuildBitCast(gallivm->builder, res, int_type, ""); - res = lp_build_intrinsic_unary(gallivm->builder, intrinsic, int_type, res); - if (type.floating) - res = LLVMBuildBitCast(gallivm->builder, res, - lp_build_elem_type(gallivm, type), ""); - return res; -} - - -/** - * Byte swap every element in the vector. - * - * @param packed <vector> to convert - * @param src_type <vector> type of int16_t, int32_t, int64_t, float or - * double - * @param dst_type <vector> type to return - */ -LLVMValueRef -lp_build_bswap_vec(struct gallivm_state *gallivm, - LLVMValueRef packed, - struct lp_type src_type_vec, - struct lp_type dst_type_vec) -{ - LLVMBuilderRef builder = gallivm->builder; - LLVMTypeRef dst_type = lp_build_elem_type(gallivm, dst_type_vec); - LLVMValueRef res; - - if (src_type_vec.length == 1) { - res = lp_build_bswap(gallivm, packed, src_type_vec); - res = LLVMBuildBitCast(gallivm->builder, res, dst_type, ""); - } else { - unsigned i; - res = LLVMGetUndef(lp_build_vec_type(gallivm, dst_type_vec)); - for (i = 0; i < src_type_vec.length; ++i) { - LLVMValueRef index = lp_build_const_int32(gallivm, i); - LLVMValueRef elem = LLVMBuildExtractElement(builder, packed, index, ""); - elem = lp_build_bswap(gallivm, elem, src_type_vec); - elem = LLVMBuildBitCast(gallivm->builder, elem, dst_type, ""); - res = LLVMBuildInsertElement(gallivm->builder, res, elem, index, ""); - } - } - return res; -} - - -/** * Converts int16 half-float to float32 * Note this can be performed in 1 instruction if vcvtph2ps exists (f16c/cvt16) * [llvm.x86.vcvtph2ps / _mm_cvtph_ps] diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h index d7dfed8..42a1113 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h @@ -43,17 +43,6 @@ struct lp_type; LLVMValueRef -lp_build_bswap(struct gallivm_state *gallivm, - LLVMValueRef res, - struct lp_type type); - -LLVMValueRef -lp_build_bswap_vec(struct gallivm_state *gallivm, - LLVMValueRef packed, - struct lp_type src_type, - struct lp_type dst_type); - -LLVMValueRef lp_build_half_to_float(struct gallivm_state *gallivm, LLVMValueRef src); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 6a1bf67..af755d4 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -139,12 +139,12 @@ format_matches_type(const struct util_format_description *desc, /** - * Unpack a single pixel into its RGBA components. + * Unpack a single pixel into its XYZW components. * * @param desc the pixel format for the packed pixel value * @param packed integer pixel in a format such as PIPE_FORMAT_B8G8R8A8_UNORM * - * @return RGBA in a float[4] or ubyte[4] or ushort[4] vector. + * @return XYZW in a float[4] or ubyte[4] or ushort[4] vector. */ static INLINE LLVMValueRef lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm, @@ -159,7 +159,6 @@ lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm, boolean normalized; boolean needs_uitofp; - unsigned shift; unsigned i; /* TODO: Support more formats */ @@ -172,10 +171,6 @@ 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} @@ -194,11 +189,11 @@ lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm, /* Initialize vector constants */ normalized = FALSE; needs_uitofp = FALSE; - shift = 0; /* Loop over 4 color components */ for (i = 0; i < 4; ++i) { unsigned bits = desc->channel[i].size; + unsigned shift = desc->channel[i].shift; if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) { shifts[i] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context)); @@ -224,12 +219,10 @@ lp_build_unpack_arith_rgba_aos(struct gallivm_state *gallivm, else scales[i] = lp_build_const_float(gallivm, 1.0); } - - shift += bits; } - /* Ex: convert packed = {BGRA, BGRA, BGRA, BGRA} - * into masked = {B, G, R, A} + /* Ex: convert packed = {XYZW, XYZW, XYZW, XYZW} + * into masked = {X, Y, Z, W} */ shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), ""); masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), ""); @@ -276,7 +269,6 @@ lp_build_pack_rgba_aos(struct gallivm_state *gallivm, LLVMValueRef shifts[4]; LLVMValueRef scales[4]; boolean normalized; - unsigned shift; unsigned i, j; assert(desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); @@ -302,9 +294,9 @@ lp_build_pack_rgba_aos(struct gallivm_state *gallivm, LLVMConstVector(swizzles, 4), ""); normalized = FALSE; - shift = 0; for (i = 0; i < 4; ++i) { unsigned bits = desc->channel[i].size; + unsigned shift = desc->channel[i].shift; if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) { shifts[i] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context)); @@ -325,8 +317,6 @@ lp_build_pack_rgba_aos(struct gallivm_state *gallivm, else scales[i] = lp_build_const_float(gallivm, 1.0); } - - shift += bits; } if (normalized) @@ -410,16 +400,11 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm, packed = lp_build_gather(gallivm, type.length/4, format_desc->block.bits, type.width*4, - base_ptr, offset); + base_ptr, offset, TRUE); 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); } @@ -453,7 +438,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm, packed = lp_build_gather_elem(gallivm, num_pixels, format_desc->block.bits, 32, - base_ptr, offset, k); + base_ptr, offset, k, FALSE); tmps[k] = lp_build_unpack_arith_rgba_aos(gallivm, format_desc, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c index 3402a0b..ee3ca86 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c @@ -40,58 +40,6 @@ #include "pipe/p_state.h" -#ifdef PIPE_ARCH_BIG_ENDIAN -static LLVMValueRef -lp_build_read_int_bswap(struct gallivm_state *gallivm, - LLVMValueRef base_ptr, - unsigned src_width, - LLVMTypeRef src_type, - unsigned i, - LLVMTypeRef dst_type) -{ - LLVMBuilderRef builder = gallivm->builder; - LLVMValueRef index = lp_build_const_int32(gallivm, i); - LLVMValueRef ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, ""); - LLVMValueRef res = LLVMBuildLoad(builder, ptr, ""); - res = lp_build_bswap(gallivm, res, lp_type_uint(src_width)); - return LLVMBuildBitCast(builder, res, dst_type, ""); -} - -static LLVMValueRef -lp_build_fetch_read_big_endian(struct gallivm_state *gallivm, - struct lp_type src_type, - LLVMValueRef base_ptr) -{ - LLVMBuilderRef builder = gallivm->builder; - unsigned src_width = src_type.width; - unsigned length = src_type.length; - LLVMTypeRef src_elem_type = LLVMIntTypeInContext(gallivm->context, src_width); - LLVMTypeRef dst_elem_type = lp_build_elem_type (gallivm, src_type); - LLVMTypeRef src_ptr_type = LLVMPointerType(src_elem_type, 0); - LLVMValueRef res; - - base_ptr = LLVMBuildPointerCast(builder, base_ptr, src_ptr_type, ""); - if (length == 1) { - /* Scalar */ - res = lp_build_read_int_bswap(gallivm, base_ptr, src_width, src_elem_type, - 0, dst_elem_type); - } else { - /* Vector */ - LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length); - unsigned i; - - res = LLVMGetUndef(dst_vec_type); - for (i = 0; i < length; ++i) { - LLVMValueRef index = lp_build_const_int32(gallivm, i); - LLVMValueRef elem = lp_build_read_int_bswap(gallivm, base_ptr, src_width, - src_elem_type, i, dst_elem_type); - res = LLVMBuildInsertElement(builder, res, elem, index, ""); - } - } - - return res; -} -#endif /** * @brief lp_build_fetch_rgba_aos_array @@ -124,13 +72,9 @@ lp_build_fetch_rgba_aos_array(struct gallivm_state *gallivm, /* Read whole vector from memory, unaligned */ ptr = LLVMBuildGEP(builder, base_ptr, &offset, 1, ""); -#ifdef PIPE_ARCH_BIG_ENDIAN - res = lp_build_fetch_read_big_endian(gallivm, src_type, ptr); -#else ptr = LLVMBuildPointerCast(builder, ptr, LLVMPointerType(src_vec_type, 0), ""); res = LLVMBuildLoad(builder, ptr, ""); lp_set_load_alignment(res, src_type.width / 8); -#endif /* Truncate doubles to float */ if (src_type.floating && src_type.width == 64) { diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index edc2442..4c6bd81 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -115,7 +115,6 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, LLVMBuilderRef builder = gallivm->builder; struct lp_build_context bld; LLVMValueRef inputs[4]; - unsigned start; unsigned chan; assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); @@ -128,9 +127,9 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, lp_build_context_init(&bld, gallivm, type); /* Decode the input vector components */ - start = 0; for (chan = 0; chan < format_desc->nr_channels; ++chan) { const unsigned width = format_desc->channel[chan].size; + const unsigned start = format_desc->channel[chan].shift; const unsigned stop = start + width; LLVMValueRef input; @@ -256,8 +255,6 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, } inputs[chan] = input; - - start = stop; } lp_build_format_swizzle_soa(format_desc, &bld, inputs, rgba_out); @@ -291,7 +288,11 @@ lp_build_rgba8_to_fi32_soa(struct gallivm_state *gallivm, /* Decode the input vector components */ for (chan = 0; chan < 4; ++chan) { +#ifdef PIPE_ARCH_LITTLE_ENDIAN unsigned start = chan*8; +#else + unsigned start = (3-chan)*8; +#endif unsigned stop = start + 8; LLVMValueRef input; @@ -360,13 +361,14 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, /* * gather the texels from the texture - * Ex: packed = {BGRA, BGRA, BGRA, BGRA}. + * Ex: packed = {XYZW, XYZW, XYZW, XYZW} */ + assert(format_desc->block.bits <= type.width); packed = lp_build_gather(gallivm, type.length, format_desc->block.bits, type.width, - base_ptr, offset); + base_ptr, offset, FALSE); /* * convert texels to float rgba @@ -391,7 +393,8 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, packed = lp_build_gather(gallivm, type.length, format_desc->block.bits, - type.width, base_ptr, offset); + type.width, base_ptr, offset, + FALSE); if (format_desc->format == PIPE_FORMAT_R11G11B10_FLOAT) { lp_build_r11g11b10_to_float(gallivm, packed, rgba_out); } @@ -418,14 +421,14 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, LLVMValueRef s_offset = lp_build_const_int_vec(gallivm, type, 4); offset = LLVMBuildAdd(builder, offset, s_offset, ""); packed = lp_build_gather(gallivm, type.length, - 32, type.width, base_ptr, offset); + 32, type.width, base_ptr, offset, FALSE); packed = LLVMBuildAnd(builder, packed, lp_build_const_int_vec(gallivm, type, mask), ""); } else { assert (format_desc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT); packed = lp_build_gather(gallivm, type.length, - 32, type.width, base_ptr, offset); + 32, type.width, base_ptr, offset, TRUE); packed = LLVMBuildBitCast(builder, packed, lp_build_vec_type(gallivm, type), ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c index e542abc..873f354 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c @@ -497,7 +497,7 @@ lp_build_fetch_subsampled_rgba_aos(struct gallivm_state *gallivm, assert(format_desc->block.width == 2); assert(format_desc->block.height == 1); - packed = lp_build_gather(gallivm, n, 32, 32, base_ptr, offset); + packed = lp_build_gather(gallivm, n, 32, 32, base_ptr, offset, FALSE); (void)j; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.c b/src/gallium/auxiliary/gallivm/lp_bld_gather.c index eefb23a..9155d81 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_gather.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_gather.c @@ -78,7 +78,8 @@ lp_build_gather_elem(struct gallivm_state *gallivm, unsigned dst_width, LLVMValueRef base_ptr, LLVMValueRef offsets, - unsigned i) + unsigned i, + boolean vector_justify) { LLVMTypeRef src_type = LLVMIntTypeInContext(gallivm->context, src_width); LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0); @@ -97,10 +98,12 @@ lp_build_gather_elem(struct gallivm_state *gallivm, res = LLVMBuildTrunc(gallivm->builder, res, dst_elem_type, ""); } else if (src_width < dst_width) { res = LLVMBuildZExt(gallivm->builder, res, dst_elem_type, ""); + if (vector_justify) { #ifdef PIPE_ARCH_BIG_ENDIAN - res = LLVMBuildShl(gallivm->builder, res, - LLVMConstInt(dst_elem_type, dst_width - src_width, 0), ""); + res = LLVMBuildShl(gallivm->builder, res, + LLVMConstInt(dst_elem_type, dst_width - src_width, 0), ""); #endif + } } return res; @@ -112,11 +115,20 @@ lp_build_gather_elem(struct gallivm_state *gallivm, * Use for fetching texels from a texture. * For SSE, typical values are length=4, src_width=32, dst_width=32. * + * When src_width < dst_width, the return value can be justified in + * one of two ways: + * "integer justification" is used when the caller treats the destination + * as a packed integer bitmask, as described by the channels' "shift" and + * "width" fields; + * "vector justification" is used when the caller casts the destination + * to a vector and needs channel X to be in vector element 0. + * * @param length length of the offsets * @param src_width src element width in bits * @param dst_width result element width in bits (src will be expanded to fit) * @param base_ptr base pointer, should be a i8 pointer type. * @param offsets vector with offsets + * @param vector_justify select vector rather than integer justification */ LLVMValueRef lp_build_gather(struct gallivm_state *gallivm, @@ -124,7 +136,8 @@ lp_build_gather(struct gallivm_state *gallivm, unsigned src_width, unsigned dst_width, LLVMValueRef base_ptr, - LLVMValueRef offsets) + LLVMValueRef offsets, + boolean vector_justify) { LLVMValueRef res; @@ -132,7 +145,7 @@ lp_build_gather(struct gallivm_state *gallivm, /* Scalar */ return lp_build_gather_elem(gallivm, length, src_width, dst_width, - base_ptr, offsets, 0); + base_ptr, offsets, 0, vector_justify); } else { /* Vector */ @@ -146,7 +159,7 @@ lp_build_gather(struct gallivm_state *gallivm, LLVMValueRef elem; elem = lp_build_gather_elem(gallivm, length, src_width, dst_width, - base_ptr, offsets, i); + base_ptr, offsets, i, vector_justify); res = LLVMBuildInsertElement(gallivm->builder, res, elem, index, ""); } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.h b/src/gallium/auxiliary/gallivm/lp_bld_gather.h index 8e4c07d..ee69473 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_gather.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_gather.h @@ -47,7 +47,8 @@ lp_build_gather_elem(struct gallivm_state *gallivm, unsigned dst_width, LLVMValueRef base_ptr, LLVMValueRef offsets, - unsigned i); + unsigned i, + boolean vector_justify); LLVMValueRef lp_build_gather(struct gallivm_state *gallivm, @@ -55,7 +56,8 @@ lp_build_gather(struct gallivm_state *gallivm, unsigned src_width, unsigned dst_width, LLVMValueRef base_ptr, - LLVMValueRef offsets); + LLVMValueRef offsets, + boolean vector_justify); LLVMValueRef lp_build_gather_values(struct gallivm_state * gallivm, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index c31b05d..104c24d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -531,7 +531,7 @@ lp_build_sample_fetch_image_nearest(struct lp_build_sample_context *bld, bld->texel_type.length, bld->format_desc->block.bits, bld->texel_type.width, - data_ptr, offset); + data_ptr, offset, TRUE); rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, ""); } @@ -893,7 +893,7 @@ lp_build_sample_fetch_image_linear(struct lp_build_sample_context *bld, bld->texel_type.length, bld->format_desc->block.bits, bld->texel_type.width, - data_ptr, offset[k][j][i]); + data_ptr, offset[k][j][i], TRUE); rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c index 08d817a..79116bc 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; } diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 4cace6a..9774a2b 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -133,6 +133,7 @@ struct util_format_channel_description unsigned normalized:1; unsigned pure_integer:1; unsigned size:9; /**< bits per channel */ + unsigned shift:16; /** number of bits from lsb */ }; @@ -179,9 +180,31 @@ struct util_format_description unsigned is_mixed:1; /** - * Input channel description. + * Input channel description, in the order XYZW. * * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. + * + * If each channel is accessed as an individual N-byte value, X is always + * at the lowest address in memory, Y is always next, and so on. For all + * currently-defined formats, the N-byte value has native endianness. + * + * If instead a group of channels is accessed as a single N-byte value, + * the order of the channels within that value depends on endianness. + * For big-endian targets, X is the most significant subvalue, + * otherwise it is the least significant one. + * + * For example, if X is 8 bits and Y is 24 bits, the memory order is: + * + * 0 1 2 3 + * little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper) + * big-endian: X Yu Ym Yl + * + * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is: + * + * 0 1 + * msb lsb msb lsb + * little-endian: YYYXXXXX WZZZZZYY + * big-endian: XXXXXYYY YYZZZZZW */ struct util_format_channel_description channel[4]; diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index 565d059..d1f68c8 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -99,15 +99,6 @@ def generate_format_type(format): print -def bswap_format(format): - '''Generate a structure that describes the format.''' - - if format.is_bitmask() and not format.is_array() and format.block_size() > 8: - print '#ifdef PIPE_ARCH_BIG_ENDIAN' - print ' pixel.value = util_bswap%u(pixel.value);' % format.block_size() - print '#endif' - - def is_format_supported(format): '''Determines whether we actually have the plumbing necessary to generate the to read/write to/from this format.''' @@ -423,16 +414,11 @@ def generate_unpack_kernel(format, dst_channel, dst_native_type): elif src_channel.type == SIGNED: print ' int%u_t %s;' % (depth, src_channel.name) - if depth > 8: - print '#ifdef PIPE_ARCH_BIG_ENDIAN' - print ' value = util_bswap%u(value);' % depth - print '#endif' - # Compute the intermediate unshifted values - shift = 0 for i in range(format.nr_channels()): src_channel = format.channels[i] value = 'value' + shift = src_channel.shift if src_channel.type == UNSIGNED: if shift: value = '%s >> %u' % (value, shift) @@ -455,8 +441,6 @@ def generate_unpack_kernel(format, dst_channel, dst_native_type): if value is not None: print ' %s = %s;' % (src_channel.name, value) - shift += src_channel.size - # Convert, swizzle, and store final values for i in range(4): swizzle = format.swizzles[i] @@ -484,7 +468,6 @@ def generate_unpack_kernel(format, dst_channel, dst_native_type): else: print ' union util_format_%s pixel;' % format.short_name() print ' memcpy(&pixel, src, sizeof pixel);' - bswap_format(format) for i in range(4): swizzle = format.swizzles[i] @@ -525,9 +508,9 @@ def generate_pack_kernel(format, src_channel, src_native_type): depth = format.block_size() print ' uint%u_t value = 0;' % depth - shift = 0 for i in range(4): dst_channel = format.channels[i] + shift = dst_channel.shift if inv_swizzle[i] is not None: value ='src[%u]' % inv_swizzle[i] dst_colorspace = format.colorspace @@ -551,13 +534,6 @@ def generate_pack_kernel(format, src_channel, src_native_type): if value is not None: print ' value |= %s;' % (value) - shift += dst_channel.size - - if depth > 8: - print '#ifdef PIPE_ARCH_BIG_ENDIAN' - print ' value = util_bswap%u(value);' % depth - print '#endif' - print ' *(uint%u_t *)dst = value;' % depth else: @@ -579,7 +555,6 @@ def generate_pack_kernel(format, src_channel, src_native_type): dst_colorspace = dst_colorspace) print ' pixel.chan.%s = %s;' % (dst_channel.name, value) - bswap_format(format) print ' memcpy(dst, &pixel, sizeof pixel);' diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py index 07052b9..e202099 100755 --- a/src/gallium/auxiliary/util/u_format_parse.py +++ b/src/gallium/auxiliary/util/u_format_parse.py @@ -30,6 +30,8 @@ ''' +import sys + VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5) SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7) @@ -42,6 +44,9 @@ YUV = 'yuv' ZS = 'zs' +# Not cross-compiler friendly +is_big_endian = sys.byteorder == 'big' + def is_pot(x): return (x & (x - 1)) == 0 @@ -307,6 +312,11 @@ def parse(filename): channel = Channel(type, norm, pure, size, names[i]) channels.append(channel) + shift = 0 + for channel in channels[3::-1] if is_big_endian else channels: + channel.shift = shift + shift += channel.size + format = Format(name, layout, block_width, block_height, channels, swizzles, colorspace) formats.append(format) return formats diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py index 8edb505..9d44cf3 100755 --- a/src/gallium/auxiliary/util/u_format_table.py +++ b/src/gallium/auxiliary/util/u_format_table.py @@ -114,9 +114,9 @@ def write_format_table(formats): else: sep = "" if channel.size: - print " {%s, %s, %s, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), bool_map(channel.pure), channel.size, sep, "xyzw"[i], channel.name) + print " {%s, %s, %s, %u, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), bool_map(channel.pure), channel.size, channel.shift, sep, "xyzw"[i], channel.name) else: - print " {0, 0, 0, 0}%s" % (sep,) + print " {0, 0, 0, 0, 0}%s" % (sep,) print " }," print " {" for i in range(4): diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 1f6a56a..102ad60 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -65,32 +65,32 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, enum pipe_format format, union util_color *uc) { switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { uc->ui = (r << 24) | (g << 16) | (b << 8) | a; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { uc->ui = (a << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | a; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } @@ -166,7 +166,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, ubyte *r, ubyte *g, ubyte *b, ubyte *a) { switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 24) & 0xff); @@ -175,7 +175,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 24) & 0xff); @@ -184,7 +184,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); @@ -193,7 +193,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 24) & 0xff); } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); @@ -202,7 +202,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) 0xff; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); @@ -211,7 +211,7 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) ((p >> 0) & 0xff); } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); @@ -350,32 +350,32 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * } switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_ABGR8888_UNORM: { uc->ui = (r << 24) | (g << 16) | (b << 8) | a; } return; - case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_XBGR8888_UNORM: { uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: { uc->ui = (a << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: { uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; } return; - case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_ARGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | a; } return; - case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_XRGB8888_UNORM: { uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } diff --git a/src/gallium/docs/source/format.rst b/src/gallium/docs/source/format.rst new file mode 100644 index 0000000..f6d77d6 --- /dev/null +++ b/src/gallium/docs/source/format.rst @@ -0,0 +1,61 @@ +Formats in gallium +================== + +Gallium format names mostly follow D3D10 conventions, with some extensions. + +Format names like XnYnZnWn have the X component in the lowest-address n bits +and the W component in the highest-address n bits; for B8G8R8A8, byte 0 is +blue and byte 3 is alpha. Note that platform endianness is not considered +in this definition. In C: + + struct x8y8z8w8 { uint8_t x, y, z, w; }; + +Format aliases like XYZWstrq are (s+t+r+q)-bit integers in host endianness, +with the X component in the s least-significant bits of the integer. In C: + + uint32_t xyzw8888 = (x << 0) | (y << 8) | (z << 16) | (w << 24); + +Format suffixes affect the interpretation of the channel: + +- ``SINT``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1] +- ``SNORM``: N bit signed integer normalized to [-1 ... 1] +- ``SSCALED``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1] +- ``FIXED``: Signed fixed point integer, (N/2 - 1) bits of mantissa +- ``FLOAT``: N bit IEEE754 float +- ``NORM``: Normalized integers, signed or unsigned per channel +- ``UINT``: N bit unsigned integer [0 ... 2^N - 1] +- ``UNORM``: N bit unsigned integer normalized to [0 ... 1] +- ``USCALED``: N bit unsigned integer [0 ... 2^N - 1] + +The difference between ``SINT`` and ``SSCALED`` is that the former are pure +integers in shaders, while the latter are floats; likewise for ``UINT`` versus +``USCALED``. + +There are two exceptions for ``FLOAT``. ``R9G9B9E5_FLOAT`` is nine bits +each of red green and blue mantissa, with a shared five bit exponent. +``R11G11B10_FLOAT`` is five bits of exponent and five or six bits of mantissa +for each color channel. + +For the ``NORM`` suffix, the signedness of each channel is indicated with an +S or U after the number of channel bits, as in ``R5SG5SB6U_NORM``. + +The ``SRGB`` suffix is like ``UNORM`` in range, but in the sRGB colorspace. + +Compressed formats are named first by the compression format string (``DXT1``, +``ETC1``, etc), followed by a format-specific subtype. Refer to the +appropriate compression spec for details. + +Formats used in video playback are named by their FOURCC code. + +Format names with an embedded underscore are subsampled. ``R8G8_B8G8`` is a +single 32-bit block of two pixels, where the R and B values are repeated in +both pixels. + +References +---------- + +DirectX Graphics Infrastructure documentation on DXGI_FORMAT enum: +http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx + +FOURCC codes for YUV formats: +http://www.fourcc.org/yuv.php diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index 79891cf..06556dc 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -349,8 +349,6 @@ get_z_shift_and_mask(const struct util_format_description *format_desc, { unsigned total_bits; unsigned z_swizzle; - unsigned chan; - unsigned padding_left, padding_right; assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); assert(format_desc->block.width == 1); @@ -365,25 +363,14 @@ get_z_shift_and_mask(const struct util_format_description *format_desc, return FALSE; *width = format_desc->channel[z_swizzle].size; + *shift = format_desc->channel[z_swizzle].shift; - padding_right = 0; - for (chan = 0; chan < z_swizzle; ++chan) - padding_right += format_desc->channel[chan].size; - - padding_left = - total_bits - (padding_right + *width); - - if (padding_left || padding_right) { - unsigned long long mask_left = (1ULL << (total_bits - padding_left)) - 1; - unsigned long long mask_right = (1ULL << (padding_right)) - 1; - *mask = mask_left ^ mask_right; - } - else { + if (*width == total_bits) { *mask = 0xffffffff; + } else { + *mask = ((1 << *width) - 1) << *shift; } - *shift = padding_right; - return TRUE; } @@ -398,7 +385,7 @@ get_s_shift_and_mask(const struct util_format_description *format_desc, unsigned *shift, unsigned *mask) { unsigned s_swizzle; - unsigned chan, sz; + unsigned sz; s_swizzle = format_desc->swizzle[1]; @@ -407,16 +394,14 @@ get_s_shift_and_mask(const struct util_format_description *format_desc, /* just special case 64bit d/s format */ if (format_desc->block.bits > 32) { + /* XXX big-endian? */ assert(format_desc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT); *shift = 0; *mask = 0xff; return TRUE; } - *shift = 0; - for (chan = 0; chan < s_swizzle; chan++) - *shift += format_desc->channel[chan].size; - + *shift = format_desc->channel[s_swizzle].shift; sz = format_desc->channel[s_swizzle].size; *mask = (1U << sz) - 1U; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index fc2ba5e..38e9fc7 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1015,12 +1015,17 @@ convert_to_blend_type(struct gallivm_state *gallivm, for (i = 0; i < num_srcs; ++i) { LLVMValueRef chans[4]; LLVMValueRef res = NULL; - unsigned sa = 0; dst[i] = LLVMBuildZExt(builder, src[i], lp_build_vec_type(gallivm, src_type), ""); for (j = 0; j < src_fmt->nr_channels; ++j) { unsigned mask = 0; + unsigned sa = src_fmt->channel[j].shift; +#ifdef PIPE_ARCH_LITTLE_ENDIAN + unsigned from_lsb = j; +#else + unsigned from_lsb = src_fmt->nr_channels - j - 1; +#endif for (k = 0; k < src_fmt->channel[j].size; ++k) { mask |= 1 << k; @@ -1046,11 +1051,9 @@ convert_to_blend_type(struct gallivm_state *gallivm, /* Insert bits into correct position */ chans[j] = LLVMBuildShl(builder, chans[j], - lp_build_const_int_vec(gallivm, src_type, j * blend_type.width), + lp_build_const_int_vec(gallivm, src_type, from_lsb * blend_type.width), ""); - sa += src_fmt->channel[j].size; - if (j == 0) { res = chans[j]; } else { @@ -1166,12 +1169,17 @@ convert_from_blend_type(struct gallivm_state *gallivm, for (i = 0; i < num_srcs; ++i) { LLVMValueRef chans[4]; LLVMValueRef res = NULL; - unsigned sa = 0; dst[i] = LLVMBuildBitCast(builder, src[i], lp_build_vec_type(gallivm, src_type), ""); for (j = 0; j < src_fmt->nr_channels; ++j) { unsigned mask = 0; + unsigned sa = src_fmt->channel[j].shift; +#ifdef PIPE_ARCH_LITTLE_ENDIAN + unsigned from_lsb = j; +#else + unsigned from_lsb = src_fmt->nr_channels - j - 1; +#endif assert(blend_type.width > src_fmt->channel[j].size); @@ -1182,7 +1190,7 @@ convert_from_blend_type(struct gallivm_state *gallivm, /* Extract bits */ chans[j] = LLVMBuildLShr(builder, dst[i], - lp_build_const_int_vec(gallivm, src_type, j * blend_type.width), + lp_build_const_int_vec(gallivm, src_type, from_lsb * blend_type.width), ""); chans[j] = LLVMBuildAnd(builder, diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 098b25b..f181621 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -33,6 +33,7 @@ extern "C" { #endif +#include "p_config.h" enum pipe_type { PIPE_TYPE_UNORM = 0, @@ -343,6 +344,27 @@ enum pipe_format { PIPE_FORMAT_COUNT }; +#if defined(PIPE_ARCH_LITTLE_ENDIAN) +#define PIPE_FORMAT_RGBA8888_UNORM PIPE_FORMAT_R8G8B8A8_UNORM +#define PIPE_FORMAT_RGBX8888_UNORM PIPE_FORMAT_R8G8B8X8_UNORM +#define PIPE_FORMAT_BGRA8888_UNORM PIPE_FORMAT_B8G8R8A8_UNORM +#define PIPE_FORMAT_BGRX8888_UNORM PIPE_FORMAT_B8G8R8X8_UNORM +#define PIPE_FORMAT_ARGB8888_UNORM PIPE_FORMAT_A8R8G8B8_UNORM +#define PIPE_FORMAT_XRGB8888_UNORM PIPE_FORMAT_X8R8G8B8_UNORM +#define PIPE_FORMAT_ABGR8888_UNORM PIPE_FORMAT_A8B8G8R8_UNORM +#define PIPE_FORMAT_XBGR8888_UNORM PIPE_FORMAT_X8B8G8R8_UNORM +#elif defined(PIPE_ARCH_BIG_ENDIAN) +#define PIPE_FORMAT_ABGR8888_UNORM PIPE_FORMAT_R8G8B8A8_UNORM +#define PIPE_FORMAT_XBGR8888_UNORM PIPE_FORMAT_R8G8B8X8_UNORM +#define PIPE_FORMAT_XRGB8888_UNORM PIPE_FORMAT_B8G8R8X8_UNORM +#define PIPE_FORMAT_ARGB8888_UNORM PIPE_FORMAT_B8G8R8A8_UNORM +#define PIPE_FORMAT_XRGB8888_UNORM PIPE_FORMAT_B8G8R8X8_UNORM +#define PIPE_FORMAT_BGRA8888_UNORM PIPE_FORMAT_A8R8G8B8_UNORM +#define PIPE_FORMAT_BGRX8888_UNORM PIPE_FORMAT_X8R8G8B8_UNORM +#define PIPE_FORMAT_RGBA8888_UNORM PIPE_FORMAT_A8B8G8R8_UNORM +#define PIPE_FORMAT_RGBX8888_UNORM PIPE_FORMAT_X8B8G8R8_UNORM +#endif + enum pipe_video_chroma_format { PIPE_VIDEO_CHROMA_FORMAT_420, diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index e09fe1d..6a037c4 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -87,8 +87,8 @@ dri_fill_in_modes(struct dri_screen *screen) MESA_FORMAT_RGB565, }; static const enum pipe_format pipe_formats[3] = { - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, + PIPE_FORMAT_BGRX8888_UNORM, PIPE_FORMAT_B5G6R5_UNORM, }; gl_format format; @@ -250,9 +250,9 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, if (mode->redBits == 8) { if (mode->alphaBits == 8) - stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; + stvis->color_format = PIPE_FORMAT_BGRA8888_UNORM; else - stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; + stvis->color_format = PIPE_FORMAT_BGRX8888_UNORM; } else { stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; } diff --git a/src/gallium/state_trackers/gbm/gbm_drm.c b/src/gallium/state_trackers/gbm/gbm_drm.c index 8490480..725f12f 100644 --- a/src/gallium/state_trackers/gbm/gbm_drm.c +++ b/src/gallium/state_trackers/gbm/gbm_drm.c @@ -45,9 +45,9 @@ gbm_format_to_gallium(enum gbm_bo_format format) { switch (format) { case GBM_BO_FORMAT_XRGB8888: - return PIPE_FORMAT_B8G8R8X8_UNORM; + return PIPE_FORMAT_BGRX8888_UNORM; case GBM_BO_FORMAT_ARGB8888: - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_BGRA8888_UNORM; default: return PIPE_FORMAT_NONE; } @@ -145,10 +145,10 @@ gbm_gallium_drm_bo_import(struct gbm_device *gbm, bo->base.base.height = resource->height0; switch (resource->format) { - case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_BGRX8888_UNORM: bo->base.base.format = GBM_BO_FORMAT_XRGB8888; break; - case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_BGRA8888_UNORM: bo->base.base.format = GBM_BO_FORMAT_ARGB8888; break; default: diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index daf5ad4..bb2dd8e 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -328,10 +328,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_R8G8B8A8_UNORM; + return PIPE_FORMAT_RGBA8888_UNORM; } else { - return PIPE_FORMAT_A8B8G8R8_UNORM; + return PIPE_FORMAT_ABGR8888_UNORM; } } else if ( GET_REDMASK(v) == 0xff0000 @@ -340,10 +340,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_BGRA8888_UNORM; } else { - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_ARGB8888_UNORM; } } else if ( GET_REDMASK(v) == 0x0000ff00 @@ -352,10 +352,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_ARGB8888_UNORM; } else { - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_BGRA8888_UNORM; } } else if ( GET_REDMASK(v) == 0xf800 diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c index 2827747..148837c 100644 --- a/src/gallium/targets/graw-xlib/graw_xlib.c +++ b/src/gallium/targets/graw-xlib/graw_xlib.c @@ -89,13 +89,13 @@ graw_create_window_and_screen( int x, if (visinfo->red_mask == 0xff0000 && visinfo->green_mask == 0xff00 && visinfo->blue_mask == 0xff) { - if (format != PIPE_FORMAT_B8G8R8A8_UNORM) + if (format != PIPE_FORMAT_BGRA8888_UNORM) goto fail; } else if (visinfo->red_mask == 0xff && visinfo->green_mask == 0xff00 && visinfo->blue_mask == 0xff0000) { - if (format != PIPE_FORMAT_R8G8B8A8_UNORM) + if (format != PIPE_FORMAT_RGBA8888_UNORM) goto fail; } else { diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c index 6afdf40..77c59db 100644 --- a/src/gallium/tests/graw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -10,8 +10,8 @@ #include "pipe/p_defines.h" enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index 685be92..38a2c4b 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -31,8 +31,8 @@ static void usage(char *name) enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/graw_util.h b/src/gallium/tests/graw/graw_util.h index 84456b4..8557285 100644 --- a/src/gallium/tests/graw/graw_util.h +++ b/src/gallium/tests/graw/graw_util.h @@ -32,8 +32,8 @@ graw_util_create_window(struct graw_info *info, int num_cbufs, bool zstencil_buf) { static const enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; enum pipe_format format; @@ -226,7 +226,7 @@ graw_util_create_tex2d(const struct graw_info *info, struct pipe_box box; temp.target = PIPE_TEXTURE_2D; - temp.format = PIPE_FORMAT_B8G8R8A8_UNORM; + temp.format = format; temp.width0 = width; temp.height0 = height; temp.depth0 = 1; diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c index 9100272..969ffa7 100644 --- a/src/gallium/tests/graw/quad-sample.c +++ b/src/gallium/tests/graw/quad-sample.c @@ -18,8 +18,8 @@ #include <stdio.h> enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c index 014e0cc..3076210 100644 --- a/src/gallium/tests/graw/shader-leak.c +++ b/src/gallium/tests/graw/shader-leak.c @@ -18,8 +18,8 @@ static int num_iters = 100; enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGR8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index 535825e..37323aa 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -14,8 +14,8 @@ #include "util/u_inlines.h" enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index d00e7e9..f84463d 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -17,8 +17,8 @@ enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index bfb40be..5a7d0a0 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -32,8 +32,8 @@ static void usage(char *name) enum pipe_format formats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_RGBA8888_UNORM, + PIPE_FORMAT_BGRA8888_UNORM, PIPE_FORMAT_NONE }; |