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.py163
1 files changed, 4 insertions, 159 deletions
diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
index a7a91ea652..1c9be1b538 100644
--- a/src/gallium/auxiliary/util/u_format_access.py
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -39,7 +39,7 @@
import sys
-from u_format_parse import *
+from u_format_pack import *
def is_format_supported(format):
@@ -94,160 +94,6 @@ def native_type(format):
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(channel):
- '''Get the number of the bit that matches unity for this channel.'''
- if channel.type == 'FLOAT':
- assert False
- if not channel.norm:
- return 0
- if channel.type == UNSIGNED:
- return channel.size
- if channel.type == SIGNED:
- return channel.size - 1
- if channel.type == FIXED:
- return channel.size / 2
- assert False
-
-
-def get_one(channel):
- '''Get the value of unity for this channel.'''
- if channel.type == 'FLOAT' or not channel.norm:
- return 1
- else:
- return (1 << get_one_shift(channel)) - 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_channel, dst_channel, dst_native_type, value):
- '''Generate the expression to clamp the value in the source type to the
- destination type range.'''
-
- if src_channel == dst_channel:
- return value
-
- # Pick the approriate clamp function
- if src_channel.type == FLOAT:
- if src_channel.size == 32:
- func = 'clampf'
- elif src_channel.size == 64:
- func = 'clamp'
- else:
- assert False
- elif src_channel.type == UNSIGNED:
- func = 'clampui'
- elif src_channel.type == SIGNED:
- func = 'clampsi'
- else:
- assert False
-
- # Clamp floats to [-1, 1] or [0, 1] range
- if src_channel.type == FLOAT and dst_channel.norm:
- max = 1
- if src_channel.sign and dst_channel.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_channel, dst_channel, dst_native_type, value):
- '''Generate the expression to convert a value between two types.'''
-
- if src_channel == dst_channel:
- return value
-
- if src_channel.type == FLOAT and dst_channel.type == FLOAT:
- return '(%s)%s' % (dst_native_type, value)
-
- if not src_channel.norm and not dst_channel.norm:
- return '(%s)%s' % (dst_native_type, value)
-
- value = clamp_expr(src_channel, dst_channel, dst_native_type, value)
-
- if dst_channel.type == FLOAT:
- if src_channel.norm:
- one = get_one(src_channel)
- if src_channel.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_channel.type == FLOAT:
- if dst_channel.norm:
- dst_one = get_one(dst_channel)
- if dst_channel.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_channel.type == dst_channel.type:
- src_one = get_one(src_channel)
- dst_one = get_one(dst_channel)
-
- if src_one > dst_one and src_channel.norm and dst_channel.norm:
- # We can just bitshift
- src_shift = get_one_shift(src_channel)
- dst_shift = get_one_shift(dst_channel)
- 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_channel.size + dst_channel.size, src_channel.sign and dst_channel.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_channel, dst_native_type, dst_suffix):
'''Generate the function to read pixels from a particular format'''
@@ -302,9 +148,10 @@ def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
for i in range(4):
src_channel = format.channels[i]
if names[i]:
- value = '(*src_pixel++)'
+ 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
@@ -454,12 +301,10 @@ 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 = Channel(FLOAT, False, 32)
native_type = 'float'
suffix = '4f'