summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util/u_format_access.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util/u_format_access.py')
-rw-r--r--src/gallium/auxiliary/util/u_format_access.py358
1 files changed, 92 insertions, 266 deletions
diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
index 0b05ddb931..1c9be1b538 100644
--- a/src/gallium/auxiliary/util/u_format_access.py
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -39,18 +39,7 @@
import sys
-from u_format_parse import *
-
-
-def short_name(format):
- '''Make up a short norm for a format, suitable to be used as suffix in
- function names.'''
-
- name = format.name
- if name.startswith('PIPE_FORMAT_'):
- name = name[len('PIPE_FORMAT_'):]
- name = name.lower()
- return name
+from u_format_pack import *
def is_format_supported(format):
@@ -63,16 +52,16 @@ def is_format_supported(format):
if format.colorspace not in ('rgb', 'zs'):
return False
- if format.layout not in (ARITH, ARRAY):
+ if format.layout != PLAIN:
return False
for i in range(4):
- type = format.in_types[i]
- if type.kind not in (VOID, UNSIGNED, FLOAT):
+ channel = format.channels[i]
+ if channel.type not in (VOID, UNSIGNED, FLOAT):
return False
# We can only read a color from a depth/stencil format if the depth channel is present
- if format.colorspace == 'zs' and format.out_swizzle[0] == SWIZZLE_NONE:
+ if format.colorspace == 'zs' and format.swizzles[0] == SWIZZLE_NONE:
return False
return True
@@ -81,187 +70,34 @@ def is_format_supported(format):
def native_type(format):
'''Get the native appropriate for a format.'''
- if format.layout == ARITH:
- # For arithmetic pixel formats return the integer type that matches the whole pixel
- return 'uint%u_t' % format.block_size()
- elif format.layout == ARRAY:
- # For array pixel formats return the integer type that matches the color channel
- type = format.in_types[0]
- if type.kind == UNSIGNED:
- return 'uint%u_t' % type.size
- elif type.kind == SIGNED:
- return 'int%u_t' % type.size
- elif type.kind == FLOAT:
- if type.size == 32:
- return 'float'
- elif type.size == 64:
- return 'double'
+ if format.layout == PLAIN:
+ if not format.is_array():
+ # For arithmetic pixel formats return the integer type that matches the whole pixel
+ return 'uint%u_t' % format.block_size()
+ else:
+ # For array pixel formats return the integer type that matches the color channel
+ channel = format.channels[0]
+ if channel.type == UNSIGNED:
+ return 'uint%u_t' % channel.size
+ elif channel.type == SIGNED:
+ return 'int%u_t' % channel.size
+ elif channel.type == FLOAT:
+ if channel.size == 32:
+ return 'float'
+ elif channel.size == 64:
+ return 'double'
+ else:
+ assert False
else:
assert False
- else:
- assert False
- else:
- assert False
-
-
-def intermediate_native_type(bits, sign):
- '''Find a native type adequate to hold intermediate results of the request bit size.'''
-
- bytes = 4 # don't use anything smaller than 32bits
- while bytes * 8 < bits:
- bytes *= 2
- bits = bytes*8
-
- if sign:
- return 'int%u_t' % bits
- else:
- return 'uint%u_t' % bits
-
-
-def get_one_shift(type):
- '''Get the number of the bit that matches unity for this type.'''
- if type.kind == 'FLOAT':
- assert False
- if not type.norm:
- return 0
- if type.kind == UNSIGNED:
- return type.size
- if type.kind == SIGNED:
- return type.size - 1
- if type.kind == FIXED:
- return type.size / 2
- assert False
-
-
-def get_one(type):
- '''Get the value of unity for this type.'''
- if type.kind == 'FLOAT' or not type.norm:
- return 1
- else:
- return (1 << get_one_shift(type)) - 1
-
-
-def generate_clamp():
- '''Code generate the clamping functions for each type.
-
- We don't use a macro so that arguments with side effects,
- like *src_pixel++ are correctly handled.
- '''
-
- for suffix, native_type in [
- ('', 'double'),
- ('f', 'float'),
- ('ui', 'unsigned int'),
- ('si', 'int'),
- ]:
- print 'static INLINE %s' % native_type
- print 'clamp%s(%s value, %s lbound, %s ubound)' % (suffix, native_type, native_type, native_type)
- print '{'
- print ' if(value < lbound)'
- print ' return lbound;'
- print ' if(value > ubound)'
- print ' return ubound;'
- print ' return value;'
- print '}'
- print
-
-
-def clamp_expr(src_type, dst_type, dst_native_type, value):
- '''Generate the expression to clamp the value in the source type to the
- destination type range.'''
-
- if src_type == dst_type:
- return value
-
- # Pick the approriate clamp function
- if src_type.kind == FLOAT:
- if src_type.size == 32:
- func = 'clampf'
- elif src_type.size == 64:
- func = 'clamp'
- else:
- assert False
- elif src_type.kind == UNSIGNED:
- func = 'clampui'
- elif src_type.kind == SIGNED:
- func = 'clampsi'
else:
assert False
- # Clamp floats to [-1, 1] or [0, 1] range
- if src_type.kind == FLOAT and dst_type.norm:
- max = 1
- if src_type.sign and dst_type.sign:
- min = -1
- else:
- min = 0
- return '%s(%s, %s, %s)' % (func, value, min, max)
-
- # FIXME: Also clamp scaled values
-
- return value
-
-
-def conversion_expr(src_type, dst_type, dst_native_type, value):
- '''Generate the expression to convert a value between two types.'''
-
- if src_type == dst_type:
- return value
- if src_type.kind == FLOAT and dst_type.kind == FLOAT:
- return '(%s)%s' % (dst_native_type, value)
-
- if not src_type.norm and not dst_type.norm:
- return '(%s)%s' % (dst_native_type, value)
-
- value = clamp_expr(src_type, dst_type, dst_native_type, value)
-
- if dst_type.kind == FLOAT:
- if src_type.norm:
- one = get_one(src_type)
- if src_type.size <= 23:
- scale = '(1.0f/0x%x)' % one
- else:
- # bigger than single precision mantissa, use double
- scale = '(1.0/0x%x)' % one
- value = '(%s * %s)' % (value, scale)
- return '(%s)%s' % (dst_native_type, value)
-
- if src_type.kind == FLOAT:
- if dst_type.norm:
- dst_one = get_one(dst_type)
- if dst_type.size <= 23:
- scale = '0x%x' % dst_one
- else:
- # bigger than single precision mantissa, use double
- scale = '(double)0x%x' % dst_one
- value = '(%s * %s)' % (value, scale)
- return '(%s)%s' % (dst_native_type, value)
-
- if src_type.kind == dst_type.kind:
- src_one = get_one(src_type)
- dst_one = get_one(dst_type)
-
- if src_one > dst_one and src_type.norm and dst_type.norm:
- # We can just bitshift
- src_shift = get_one_shift(src_type)
- dst_shift = get_one_shift(dst_type)
- value = '(%s >> %s)' % (value, src_shift - dst_shift)
- else:
- # We need to rescale using an intermediate type big enough to hold the multiplication of both
- tmp_native_type = intermediate_native_type(src_type.size + dst_type.size, src_type.sign and dst_type.sign)
- value = '(%s)%s' % (tmp_native_type, value)
- value = '%s * 0x%x / 0x%x' % (value, dst_one, src_one)
- value = '(%s)%s' % (dst_native_type, value)
- return value
-
- assert False
-
-
-def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
+def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
'''Generate the function to read pixels from a particular format'''
- name = short_name(format)
+ name = format.short_name()
src_native_type = native_type(format)
@@ -279,11 +115,11 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
names = ['']*4
if format.colorspace == 'rgb':
for i in range(4):
- swizzle = format.out_swizzle[i]
+ swizzle = format.swizzles[i]
if swizzle < 4:
names[swizzle] += 'rgba'[i]
elif format.colorspace == 'zs':
- swizzle = format.out_swizzle[0]
+ swizzle = format.swizzles[0]
if swizzle < 4:
names[swizzle] = 'z'
else:
@@ -291,64 +127,66 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
else:
assert False
- if format.layout == ARITH:
- print ' %s pixel = *src_pixel++;' % src_native_type
- shift = 0;
- for i in range(4):
- src_type = format.in_types[i]
- width = src_type.size
- if names[i]:
- value = 'pixel'
- mask = (1 << width) - 1
- if shift:
- value = '(%s >> %u)' % (value, shift)
- if shift + width < format.block_size():
- value = '(%s & 0x%x)' % (value, mask)
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' %s %s = %s;' % (dst_native_type, names[i], value)
- shift += width
- elif format.layout == ARRAY:
- for i in range(4):
- src_type = format.in_types[i]
- if names[i]:
- value = '(*src_pixel++)'
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ if format.layout == PLAIN:
+ if not format.is_array():
+ print ' %s pixel = *src_pixel++;' % src_native_type
+ shift = 0;
+ for i in range(4):
+ src_channel = format.channels[i]
+ width = src_channel.size
+ if names[i]:
+ value = 'pixel'
+ mask = (1 << width) - 1
+ if shift:
+ value = '(%s >> %u)' % (value, shift)
+ if shift + width < format.block_size():
+ value = '(%s & 0x%x)' % (value, mask)
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ shift += width
+ else:
+ for i in range(4):
+ src_channel = format.channels[i]
+ if names[i]:
+ value = 'src_pixel[%u]' % i
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ print ' src_pixel += %u;' % (format.nr_channels())
else:
assert False
for i in range(4):
if format.colorspace == 'rgb':
- swizzle = format.out_swizzle[i]
+ swizzle = format.swizzles[i]
if swizzle < 4:
value = names[swizzle]
elif swizzle == SWIZZLE_0:
value = '0'
elif swizzle == SWIZZLE_1:
- value = get_one(dst_type)
+ value = get_one(dst_channel)
else:
assert False
elif format.colorspace == 'zs':
if i < 3:
value = 'z'
else:
- value = get_one(dst_type)
+ value = get_one(dst_channel)
else:
assert False
print ' *dst_pixel++ = %s; /* %s */' % (value, 'rgba'[i])
print ' }'
print ' src_row += src_stride;'
- print ' dst_row += dst_stride/sizeof(%s);' % dst_native_type
+ print ' dst_row += dst_stride/sizeof(*dst_row);'
print ' }'
print '}'
print
-def generate_format_write(format, src_type, src_native_type, src_suffix):
+def generate_format_write(format, src_channel, src_native_type, src_suffix):
'''Generate the function to write pixels to a particular format'''
- name = short_name(format)
+ name = format.short_name()
dst_native_type = native_type(format)
@@ -363,58 +201,48 @@ def generate_format_write(format, src_type, src_native_type, src_suffix):
print ' const %s *src_pixel = src_row;' %src_native_type
print ' for (x = 0; x < w; ++x) {'
- inv_swizzle = [None]*4
- if format.colorspace == 'rgb':
- for i in range(4):
- swizzle = format.out_swizzle[i]
- if swizzle < 4:
- inv_swizzle[swizzle] = i
- elif format.colorspace == 'zs':
- swizzle = format.out_swizzle[0]
- if swizzle < 4:
- inv_swizzle[swizzle] = 0
- else:
- assert False
-
- if format.layout == ARITH:
- print ' %s pixel = 0;' % dst_native_type
- shift = 0;
- for i in range(4):
- dst_type = format.in_types[i]
- width = dst_type.size
- if inv_swizzle[i] is not None:
- value = 'src_pixel[%u]' % inv_swizzle[i]
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- if shift:
- value = '(%s << %u)' % (value, shift)
- print ' pixel |= %s;' % value
- shift += width
- print ' *dst_pixel++ = pixel;'
- elif format.layout == ARRAY:
- for i in range(4):
- dst_type = format.in_types[i]
- if inv_swizzle[i] is not None:
- value = 'src_pixel[%u]' % inv_swizzle[i]
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' *dst_pixel++ = %s;' % value
+ inv_swizzle = format.inv_swizzles()
+
+ if format.layout == PLAIN:
+ if not format.is_array():
+ print ' %s pixel = 0;' % dst_native_type
+ shift = 0;
+ for i in range(4):
+ dst_channel = format.channels[i]
+ width = dst_channel.size
+ if inv_swizzle[i] is not None:
+ value = 'src_pixel[%u]' % inv_swizzle[i]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if shift:
+ value = '(%s << %u)' % (value, shift)
+ print ' pixel |= %s;' % value
+ shift += width
+ print ' *dst_pixel++ = pixel;'
+ else:
+ for i in range(4):
+ dst_channel = format.channels[i]
+ if inv_swizzle[i] is not None:
+ value = 'src_pixel[%u]' % inv_swizzle[i]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ print ' *dst_pixel++ = %s;' % value
else:
assert False
print ' src_pixel += 4;'
print ' }'
print ' dst_row += dst_stride;'
- print ' src_row += src_stride/sizeof(%s);' % src_native_type
+ print ' src_row += src_stride/sizeof(*src_row);'
print ' }'
print '}'
print
-def generate_read(formats, dst_type, dst_native_type, dst_suffix):
+def generate_read(formats, dst_channel, dst_native_type, dst_suffix):
'''Generate the dispatch function to read pixels from any format'''
for format in formats:
if is_format_supported(format):
- generate_format_read(format, dst_type, dst_native_type, dst_suffix)
+ generate_format_read(format, dst_channel, dst_native_type, dst_suffix)
print 'void'
print 'util_format_read_%s(enum pipe_format format, %s *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
@@ -424,7 +252,7 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix):
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &util_format_%s_read_%s;' % (short_name(format), dst_suffix)
+ print ' func = &util_format_%s_read_%s;' % (format.short_name(), dst_suffix)
print ' break;'
print ' default:'
print ' debug_printf("unsupported format\\n");'
@@ -435,12 +263,12 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix):
print
-def generate_write(formats, src_type, src_native_type, src_suffix):
+def generate_write(formats, src_channel, src_native_type, src_suffix):
'''Generate the dispatch function to write pixels to any format'''
for format in formats:
if is_format_supported(format):
- generate_format_write(format, src_type, src_native_type, src_suffix)
+ generate_format_write(format, src_channel, src_native_type, src_suffix)
print 'void'
print 'util_format_write_%s(enum pipe_format format, const %s *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
@@ -451,7 +279,7 @@ def generate_write(formats, src_type, src_native_type, src_suffix):
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &util_format_%s_write_%s;' % (short_name(format), src_suffix)
+ print ' func = &util_format_%s_write_%s;' % (format.short_name(), src_suffix)
print ' break;'
print ' default:'
print ' debug_printf("unsupported format\\n");'
@@ -473,20 +301,18 @@ def main():
print __doc__.strip()
print
print '#include "pipe/p_compiler.h"'
- print '#include "u_format.h"'
print '#include "u_math.h"'
+ print '#include "u_format_pack.h"'
print
- generate_clamp()
-
- type = Type(FLOAT, False, 32)
+ type = Channel(FLOAT, False, 32)
native_type = 'float'
suffix = '4f'
generate_read(formats, type, native_type, suffix)
generate_write(formats, type, native_type, suffix)
- type = Type(UNSIGNED, True, 8)
+ type = Channel(UNSIGNED, True, 8)
native_type = 'uint8_t'
suffix = '4ub'