From 2c06fa4682ec0dd8a9f9d15ace867a6b952fd2e8 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 7 Apr 2010 22:16:18 +0100 Subject: util: Support fixed formats conversion. --- src/gallium/auxiliary/util/u_format_pack.py | 53 +++++++++++++++++++++------- src/gallium/auxiliary/util/u_format_parse.py | 4 +++ src/gallium/auxiliary/util/u_format_tests.c | 35 ++++++++++++++++++ 3 files changed, 80 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index aaeb4ce34c..075f8caa30 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -57,7 +57,7 @@ def generate_format_type(format): print ' unsigned %s:%u;' % (channel.name, channel.size) elif channel.type == UNSIGNED: print ' unsigned %s:%u;' % (channel.name, channel.size) - elif channel.type == SIGNED: + elif channel.type in (SIGNED, FIXED): print ' int %s:%u;' % (channel.name, channel.size) elif channel.type == FLOAT: if channel.size == 32: @@ -111,7 +111,9 @@ def is_format_supported(format): for i in range(4): channel = format.channels[i] - if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT): + if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT, FIXED): + return False + if channel.type == FLOAT and channel.size not in (16, 32, 64): return False # We can only read a color from a depth/stencil format if the depth channel is present @@ -133,7 +135,7 @@ def native_type(format): channel = format.channels[0] if channel.type in (UNSIGNED, VOID): return 'uint%u_t' % channel.size - elif channel.type == SIGNED: + elif channel.type in (SIGNED, FIXED): return 'int%u_t' % channel.size elif channel.type == FLOAT: if channel.size == 16: @@ -179,12 +181,35 @@ def get_one_shift(type): assert False -def get_one(type): +def value_to_native(type, value): '''Get the value of unity for this type.''' - if type.type == 'FLOAT' or not type.norm: - return 1 + if type.type == FLOAT: + return value + if type.type == FIXED: + return int(value * (1 << (type.size/2))) + if not type.norm: + return int(value) + if type.type == UNSIGNED: + return int(value * ((1 << type.size) - 1)) + if type.type == SIGNED: + return int(value * ((1 << (type.size - 1)) - 1)) + assert False + + +def native_to_constant(type, value): + '''Get the value of unity for this type.''' + if type.type == FLOAT: + if type.size <= 32: + return "%ff" % value + else: + return "%ff" % value else: - return (1 << get_one_shift(type)) - 1 + return str(int(value)) + + +def get_one(type): + '''Get the value of unity for this type.''' + return value_to_native(type, 1) def clamp_expr(src_channel, dst_channel, dst_native_type, value): @@ -198,15 +223,19 @@ def clamp_expr(src_channel, dst_channel, dst_native_type, value): src_max = src_channel.max() dst_min = dst_channel.min() dst_max = dst_channel.max() + + # Translate the destination range to the src native value + dst_min_native = value_to_native(src_channel, dst_min) + dst_max_native = value_to_native(src_channel, dst_max) if src_min < dst_min and src_max > dst_max: - return 'CLAMP(%s, %s, %s)' % (value, dst_min, dst_max) + return 'CLAMP(%s, %s, %s)' % (value, dst_min_native, dst_max_native) if src_max > dst_max: - return 'MIN2(%s, %s)' % (value, dst_max) + return 'MIN2(%s, %s)' % (value, dst_max_native) if src_min < dst_min: - return 'MAX2(%s, %s)' % (value, dst_min) + return 'MAX2(%s, %s)' % (value, dst_min_native) return value @@ -290,7 +319,7 @@ def conversion_expr(src_channel, # Promote to either float or double if src_type != FLOAT: - if src_norm: + if src_norm or src_type == FIXED: one = get_one(src_channel) if src_size <= 23: value = '(%s * (1.0f/0x%x))' % (value, one) @@ -314,7 +343,7 @@ def conversion_expr(src_channel, # Convert double or float to non-float if dst_channel.type != FLOAT: - if dst_channel.norm: + if dst_channel.norm or dst_channel.type == FIXED: dst_one = get_one(dst_channel) if dst_channel.size <= 23: value = '(%s * 0x%x)' % (value, dst_one) diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py index 03dc62d329..96e6451d0d 100755 --- a/src/gallium/auxiliary/util/u_format_parse.py +++ b/src/gallium/auxiliary/util/u_format_parse.py @@ -73,6 +73,8 @@ class Channel: '''Maximum representable number.''' if self.type == FLOAT: return VERY_LARGE + if self.type == FIXED: + return (1 << (self.size/2)) - 1 if self.norm: return 1 if self.type == UNSIGNED: @@ -85,6 +87,8 @@ class Channel: '''Minimum representable number.''' if self.type == FLOAT: return -VERY_LARGE + if self.type == FIXED: + return -(1 << (self.size/2)) if self.type == UNSIGNED: return 0 if self.norm: diff --git a/src/gallium/auxiliary/util/u_format_tests.c b/src/gallium/auxiliary/util/u_format_tests.c index 55ce283f02..095c4db8e2 100644 --- a/src/gallium/auxiliary/util/u_format_tests.c +++ b/src/gallium/auxiliary/util/u_format_tests.c @@ -836,6 +836,41 @@ util_format_test_cases[] = {PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x3c00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, {PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xbc00), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, {PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x3c00, 0x3c00, 0x3c00, 0x3c00), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, + + /* + * 32-bit fixed point formats + */ + + {PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00010000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0xffff0000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, + + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00010000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffff0000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 0.0, 1.0)}, + + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00010000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffff0000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00010000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xffff0000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, + {PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00010000, 0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, + + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00010000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffff0000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00010000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xffff0000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00010000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xffff0000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, + {PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00010000, 0x00010000, 0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, }; -- cgit v1.2.3