Mesa (master): util: Factor some code into u_format_parse.py

Jose Fonseca jrfonseca at kemper.freedesktop.org
Fri Feb 26 16:47:28 UTC 2010


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Fri Feb 26 15:45:48 2010 +0000

util: Factor some code into u_format_parse.py

---

 src/gallium/auxiliary/util/u_format_access.py |   20 +-----
 src/gallium/auxiliary/util/u_format_parse.py  |   95 +++++++++++++++++++++++--
 src/gallium/auxiliary/util/u_format_table.py  |    5 +-
 src/gallium/drivers/llvmpipe/lp_tile_soa.py   |    4 +-
 4 files changed, 96 insertions(+), 28 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
index 267fb3f..a7a91ea 100644
--- a/src/gallium/auxiliary/util/u_format_access.py
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -248,24 +248,6 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value):
     assert False
 
 
-def compute_inverse_swizzle(format):
-    '''Return an array[4] of inverse swizzle terms'''
-    inv_swizzle = [None]*4
-    if format.colorspace == 'rgb':
-        for i in range(4):
-            swizzle = format.swizzles[i]
-            if swizzle < 4:
-                inv_swizzle[swizzle] = i
-    elif format.colorspace == 'zs':
-        swizzle = format.swizzles[0]
-        if swizzle < 4:
-            inv_swizzle[swizzle] = 0
-    else:
-        assert False
-
-    return inv_swizzle
-
-
 def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
     '''Generate the function to read pixels from a particular format'''
 
@@ -372,7 +354,7 @@ def generate_format_write(format, src_channel, src_native_type, src_suffix):
     print '      const %s *src_pixel = src_row;' %src_native_type
     print '      for (x = 0; x < w; ++x) {'
 
-    inv_swizzle = compute_inverse_swizzle(format)
+    inv_swizzle = format.inv_swizzles()
 
     if format.layout == PLAIN:
         if not format.is_array():
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
index edc6bba..2509264 100755
--- a/src/gallium/auxiliary/util/u_format_parse.py
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -36,19 +36,28 @@ SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE,
 
 PLAIN = 'plain'
 
+RGB = 'rgb'
+SRGB = 'srgb'
+YUV = 'yuv'
+ZS = 'zs'
+
 
 def is_pot(x):
    return (x & (x - 1)) == 0;
 
 
+VERY_LARGE = 99999999999999999999999
+
+
 class Channel:
     '''Describe the channel of a color channel.'''
     
-    def __init__(self, type, norm, size):
+    def __init__(self, type, norm, size, name = ''):
         self.type = type
         self.norm = norm
         self.size = size
         self.sign = type in (SIGNED, FIXED, FLOAT)
+        self.name = name
 
     def __str__(self):
         s = str(self.type)
@@ -60,6 +69,30 @@ class Channel:
     def __eq__(self, other):
         return self.type == other.type and self.norm == other.norm and self.size == other.size
 
+    def max(self):
+        '''Maximum representable number.'''
+        if self.type == FLOAT:
+            return VERY_LARGE
+        if self.norm:
+            return 1
+        if self.type == UNSIGNED:
+            return (1 << self.size) - 1
+        if self.type == SIGNED:
+            return self.size - 1
+        assert False
+    
+    def min(self):
+        '''Minimum representable number.'''
+        if self.type == FLOAT:
+            return -VERY_LARGE
+        if self.type == UNSIGNED:
+            return 0
+        if self.norm:
+            return -1
+        if self.type == SIGNED:
+            return -(1 << (self.size - 1))
+        assert False
+
 
 class Format:
     '''Describe a pixel format.'''
@@ -132,6 +165,29 @@ class Format:
                 return False
         return True
 
+    def is_bitmask(self):
+        if self.block_size() > 32:
+            return False
+        if not self.is_pot():
+            return False
+        for channel in self.channels:
+            if not is_pot(channel.size):
+                return True
+            if channel.type not in (VOID, UNSIGNED, SIGNED):
+                return False
+            if channel.size >= 32:
+                return False
+        return True
+
+    def inv_swizzles(self):
+        '''Return an array[4] of inverse swizzle terms'''
+        inv_swizzle = [None]*4
+        for i in range(4):
+            swizzle = self.swizzles[i]
+            if swizzle < 4:
+                inv_swizzle[swizzle] = i
+        return inv_swizzle
+
     def stride(self):
         return self.block_size()/8
 
@@ -171,12 +227,39 @@ def parse(filename):
         line = line.strip()
         if not line:
             continue
+
         fields = [field.strip() for field in line.split(',')]
+        
         name = fields[0]
         layout = fields[1]
         block_width, block_height = map(int, fields[2:4])
+
+        swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
+        colorspace = fields[9]
+        
+        if layout == PLAIN:
+            names = ['']*4
+            if colorspace in (RGB, SRGB):
+                for i in range(4):
+                    swizzle = swizzles[i]
+                    if swizzle < 4:
+                        names[swizzle] += 'rgba'[i]
+            elif colorspace == ZS:
+                for i in range(4):
+                    swizzle = swizzles[i]
+                    if swizzle < 4:
+                        names[swizzle] += 'zs'[i]
+            else:
+                assert False
+            for i in range(4):
+                if names[i] == '':
+                    names[i] = 'x'
+        else:
+            names = ['x', 'y', 'z', 'w']
+
         channels = []
-        for field in fields[4:8]:
+        for i in range(0, 4):
+            field = fields[4 + i]
             if field:
                 type = _type_parse_map[field[0]]
                 if field[1] == 'n':
@@ -189,10 +272,10 @@ def parse(filename):
                 type = VOID
                 norm = False
                 size = 0
-            channel = Channel(type, norm, size)
+            channel = Channel(type, norm, size, names[i])
             channels.append(channel)
-        swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
-        colorspace = fields[9]
-        formats.append(Format(name, layout, block_width, block_height, channels, swizzles, colorspace))
+
+        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 a7a4fd1..4e29d15 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -117,7 +117,10 @@ def write_format_table(formats):
                 sep = ","
             else:
                 sep = ""
-            print "      {%s, %s, %u}%s\t/* %s */" % (type_map[channel.type], bool_map(channel.norm), channel.size, sep, "xyzw"[i])
+            if channel.size:
+                print "      {%s, %s, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), channel.size, sep, "xyzw"[i], channel.name)
+            else:
+                print "      {0, 0, 0}%s" % (sep,)
         print "   },"
         print "   {"
         for i in range(4):
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
index 52d7d31..dc44d67 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
@@ -135,7 +135,7 @@ def pack_rgba(format, src_channel, r, g, b, a):
     given format.  Ex: '(b << 24) | (g << 16) | (r << 8) | (a << 0)'
     """
     assert format.colorspace == 'rgb'
-    inv_swizzle = compute_inverse_swizzle(format)
+    inv_swizzle = format.inv_swizzles()
     shift = 0
     expr = None
     for i in range(4):
@@ -200,7 +200,7 @@ def emit_tile_pixel_write_code(format, src_channel):
     '''Emit code for writing a block based on the TILE_PIXEL macro.'''
     dst_native_type = native_type(format)
 
-    inv_swizzle = compute_inverse_swizzle(format)
+    inv_swizzle = format.inv_swizzles()
 
     print '   unsigned x, y;'
     print '   uint8_t *dst_row = dst + y0*dst_stride;'




More information about the mesa-commit mailing list