Mesa (master): util: Support fixed formats conversion.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Apr 7 14:19:44 PDT 2010


Module: Mesa
Branch: master
Commit: 2c06fa4682ec0dd8a9f9d15ace867a6b952fd2e8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2c06fa4682ec0dd8a9f9d15ace867a6b952fd2e8

Author: José Fonseca <jfonseca at vmware.com>
Date:   Wed Apr  7 22:16:18 2010 +0100

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(-)

diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py
index aaeb4ce..075f8ca 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 03dc62d..96e6451 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 55ce283..095c4db 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)},
 };
 
 



More information about the mesa-commit mailing list