The old code tried to emulate little-endian format layout on big-endian targets by byte-swapping each pixel value. This was OK for packed byte formats, but isn't what we want for multibyte channels. E.g. the floats in R32G32B32A32_FLOAT should all have native endianness, and the red component should always come first. Formats with Z24 channels should contain a native-endian 24-bit depth value.
The idea is to have a separate list of channels and swizzles for little and big endian. At the moment the channel order and swizzles are the same for both endiannesses, only the shifts differ. This will change as more formats are "fixed" for big endian. No piglit regressions on x86_64. This patch on its own doesn't help the results much on big-endian, but it's needed by later patches that do. Signed-off-by: Richard Sandiford <rsand...@linux.vnet.ibm.com> --- src/gallium/auxiliary/util/u_format_pack.py | 34 +++++----------- src/gallium/auxiliary/util/u_format_parse.py | 60 +++++++++++++++++----------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index b4db0d1..1408085 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -51,7 +51,14 @@ def inv_swizzles(swizzles): return inv_swizzle def print_channels(format, func): - func(format.channels, format.swizzles) + if format.nr_channels() <= 1: + func(format.le_channels, format.le_swizzles) + else: + print '#ifdef PIPE_ARCH_BIG_ENDIAN' + func(format.be_channels, format.be_swizzles) + print '#else' + func(format.le_channels, format.le_swizzles) + print '#endif' def generate_format_type(format): '''Generate a structure that describes the format.''' @@ -105,7 +112,7 @@ def generate_format_type(format): print ' uint%u_t value;' % (format.block_size(),) use_bitfields = False - for channel in format.channels: + for channel in format.le_channels: if channel.size % 8 or not is_pot(channel.size): use_bitfields = True @@ -119,15 +126,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.''' @@ -138,7 +136,7 @@ def is_format_supported(format): return False for i in range(4): - channel = format.channels[i] + channel = format.le_channels[i] if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT, FIXED): return False if channel.type == FLOAT and channel.size not in (16, 32, 64): @@ -422,11 +420,6 @@ 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 for i in range(4): src_channel = channels[i] @@ -481,7 +474,6 @@ def generate_unpack_kernel(format, dst_channel, dst_native_type): def unpack_from_union(channels, swizzles): print ' union util_format_%s pixel;' % format.short_name() print ' memcpy(&pixel, src, sizeof pixel);' - bswap_format(format) for i in range(4): swizzle = swizzles[i] @@ -553,11 +545,6 @@ def generate_pack_kernel(format, src_channel, src_native_type): if value is not None: print ' value |= %s;' % (value) - 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 def pack_into_union(channels, swizzles): @@ -581,7 +568,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);' if format.is_bitmask(): diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py index d60a0a2..15cc6d4 100755 --- a/src/gallium/auxiliary/util/u_format_parse.py +++ b/src/gallium/auxiliary/util/u_format_parse.py @@ -104,13 +104,15 @@ class Channel: class Format: '''Describe a pixel format.''' - def __init__(self, name, layout, block_width, block_height, channels, swizzles, colorspace): + def __init__(self, name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace): self.name = name self.layout = layout self.block_width = block_width self.block_height = block_height - self.channels = channels - self.swizzles = swizzles + self.le_channels = le_channels + self.le_swizzles = le_swizzles + self.be_channels = be_channels + self.be_swizzles = be_swizzles self.name = name self.colorspace = colorspace @@ -129,13 +131,13 @@ class Format: def block_size(self): size = 0 - for channel in self.channels: + for channel in self.le_channels: size += channel.size return size def nr_channels(self): nr_channels = 0 - for channel in self.channels: + for channel in self.le_channels: if channel.size: nr_channels += 1 return nr_channels @@ -143,10 +145,10 @@ class Format: def array_element(self): if self.layout != PLAIN: return None - ref_channel = self.channels[0] + ref_channel = self.le_channels[0] if ref_channel.type == VOID: - ref_channel = self.channels[1] - for channel in self.channels: + ref_channel = self.le_channels[1] + for channel in self.le_channels: if channel.size and (channel.size != ref_channel.size or channel.size % 8): return None if channel.type != VOID: @@ -164,10 +166,10 @@ class Format: def is_mixed(self): if self.layout != PLAIN: return False - ref_channel = self.channels[0] + ref_channel = self.le_channels[0] if ref_channel.type == VOID: - ref_channel = self.channels[1] - for channel in self.channels[1:]: + ref_channel = self.le_channels[1] + for channel in self.le_channels[1:]: if channel.type != VOID: if channel.type != ref_channel.type: return True @@ -183,7 +185,7 @@ class Format: def is_int(self): if self.layout != PLAIN: return False - for channel in self.channels: + for channel in self.le_channels: if channel.type not in (VOID, UNSIGNED, SIGNED): return False return True @@ -191,7 +193,7 @@ class Format: def is_float(self): if self.layout != PLAIN: return False - for channel in self.channels: + for channel in self.le_channels: if channel.type not in (VOID, FLOAT): return False return True @@ -201,7 +203,7 @@ class Format: return False if self.block_size() not in (8, 16, 32): return False - for channel in self.channels: + for channel in self.le_channels: if channel.type not in (VOID, UNSIGNED, SIGNED): return False return True @@ -210,7 +212,7 @@ class Format: if self.layout != PLAIN or self.colorspace == ZS: return False pures = [channel.pure - for channel in self.channels + for channel in self.le_channels if channel.type != VOID] for x in pures: assert x == pures[0] @@ -218,7 +220,7 @@ class Format: def channel_type(self): types = [channel.type - for channel in self.channels + for channel in self.le_channels if channel.type != VOID] for x in types: assert x == types[0] @@ -231,7 +233,7 @@ class Format: return self.is_pure_color() and self.channel_type() == UNSIGNED def has_channel(self, id): - return self.swizzles[id] != SWIZZLE_NONE + return self.le_swizzles[id] != SWIZZLE_NONE def has_depth(self): return self.colorspace == ZS and self.has_channel(0) @@ -334,15 +336,25 @@ def parse(filename): block_width, block_height = map(int, fields[2:4]) colorspace = fields[9] - swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]] - channels = _parse_channels(fields[4:8], layout, colorspace, swizzles) + le_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]] + le_channels = _parse_channels(fields[4:8], layout, colorspace, le_swizzles) - shift = 0 - for channel in channels: - channel.shift = shift - shift += channel.size + be_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]] + be_channels = _parse_channels(fields[4:8], layout, colorspace, be_swizzles) - format = Format(name, layout, block_width, block_height, channels, swizzles, colorspace) + le_shift = 0 + for channel in le_channels: + channel.shift = le_shift + le_shift += channel.size + + be_shift = 0 + for channel in be_channels[3::-1]: + channel.shift = be_shift + be_shift += channel.size + + assert le_shift == be_shift + + format = Format(name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace) formats.append(format) return formats -- 1.7.11.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev