From 3d305243938980af520c6d3e0ce02f4ee3a6126c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 30 Aug 2009 12:02:36 +0100 Subject: [PATCH] util: Auto generate pixel format accessor functions from This has several advantages over the u_ - not hand written - no intermediate memcpy of raw pixels - supports 4 ubytes in addition to floats - no need to pass a pipe_transfer It also has (hopefully temporary) limitations: - no support for YUV - no support for SRGB --- src/gallium/auxiliary/util/.gitignore | 1 + src/gallium/auxiliary/util/Makefile | 6 +- src/gallium/auxiliary/util/SConscript | 8 + src/gallium/auxiliary/util/u_format.csv | 16 +- src/gallium/auxiliary/util/u_format.h | 24 + src/gallium/auxiliary/util/u_format_access.py | 498 ++++++++++++++++++ src/gallium/auxiliary/util/u_format_parse.py | 141 +++++ src/gallium/auxiliary/util/u_format_table.py | 98 +--- 8 files changed, 699 insertions(+), 93 deletions(-) create mode 100644 src/gallium/auxiliary/util/u_format_access.py create mode 100755 src/gallium/auxiliary/util/u_format_parse.py diff --git a/src/gallium/auxiliary/util/.gitignore b/src/gallium/auxiliary/util/.gitignore index 53fe9b8a652..29c586c9b51 100644 --- a/src/gallium/auxiliary/util/.gitignore +++ b/src/gallium/auxiliary/util/.gitignore @@ -1 +1,2 @@ +u_format_access.c u_format_table.c diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 77f1133096e..ae8d330a787 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -12,6 +12,7 @@ C_SOURCES = \ u_cache.c \ u_draw_quad.c \ u_format.c \ + u_format_access.c \ u_format_table.c \ u_gen_mipmap.c \ u_handle_table.c \ @@ -36,5 +37,8 @@ C_SOURCES = \ include ../../Makefile.template -u_format_table.c: u_format_table.py u_format.csv +u_format_table.c: u_format_table.py u_format_parse.py u_format.csv python u_format_table.py u_format.csv > $@ + +u_format_access.c: u_format_access.py u_format_parse.py u_format.csv + python u_format_access.py u_format.csv > $@ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 5ceb1970b5c..28a5ab42569 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -11,6 +11,13 @@ env.CodeGenerate( command = 'python $SCRIPT $SOURCE > $TARGET' ) +env.CodeGenerate( + target = 'u_format_access.c', + script = 'u_format_access.py', + source = ['u_format.csv'], + command = 'python $SCRIPT $SOURCE > $TARGET' +) + util = env.ConvenienceLibrary( target = 'util', source = [ @@ -25,6 +32,7 @@ util = env.ConvenienceLibrary( 'u_debug_symbol.c', 'u_draw_quad.c', 'u_format.c', + 'u_format_access.c', 'u_format_table.c', 'u_gen_mipmap.c', 'u_handle_table.c', diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 74bd21a838d..00a46d0cc48 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -2,23 +2,23 @@ PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw, PIPE_FORMAT_X8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyx1, rgb PIPE_FORMAT_B8G8R8A8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb PIPE_FORMAT_B8G8R8X8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb -PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb +PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un1 , un5 , un5 , un5 , zyxw, rgb PIPE_FORMAT_A4R4G4B4_UNORM , arith , 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb PIPE_FORMAT_R5G6B5_UNORM , arith , 1, 1, un5 , un6 , un5 , , zyx1, rgb -PIPE_FORMAT_A2B10G10R10_UNORM , arith , 1, 1, un10, un10, un10, un2 , wzyx, rgb +PIPE_FORMAT_A2B10G10R10_UNORM , arith , 1, 1, un10, un10, un10, un2 , xyzw, rgb PIPE_FORMAT_L8_UNORM , arith , 1, 1, un8 , , , , xxx1, rgb PIPE_FORMAT_A8_UNORM , arith , 1, 1, un8 , , , , 000x, rgb PIPE_FORMAT_I8_UNORM , arith , 1, 1, un8 , , , , xxxx, rgb PIPE_FORMAT_A8L8_UNORM , arith , 1, 1, un8 , un8 , , , xxxy, rgb PIPE_FORMAT_L16_UNORM , arith , 1, 1, un16, , , , xxx1, rgb -PIPE_FORMAT_Z16_UNORM , arith , 1, 1, un16, , , , x0__, zs -PIPE_FORMAT_Z32_UNORM , arith , 1, 1, un32, , , , x0__, zs -PIPE_FORMAT_Z32_FLOAT , arith , 1, 1, f32 , , , , x0__, zs +PIPE_FORMAT_Z16_UNORM , array , 1, 1, un16, , , , x___, zs +PIPE_FORMAT_Z32_UNORM , array , 1, 1, un32, , , , x___, zs +PIPE_FORMAT_Z32_FLOAT , array , 1, 1, f32 , , , , x___, zs PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs -PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un8 , un24, , , y0__, zs -PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un24, un8 , , , x0__, zs -PIPE_FORMAT_S8_UNORM , arith , 1, 1, un8 , , , , 0x__, zs +PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un8 , un24, , , y___, zs +PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un24, un8 , , , x___, zs +PIPE_FORMAT_S8_UNORM , array , 1, 1, un8 , , , , _x__, zs PIPE_FORMAT_R64_FLOAT , array , 1, 1, f64 , , , , x001, rgb PIPE_FORMAT_R64G64_FLOAT , array , 1, 1, f64 , f64 , , , xy01, rgb PIPE_FORMAT_R64G64B64_FLOAT , array , 1, 1, f64 , f64 , f64 , , xyz1, rgb diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index b5504ebe056..7b5b7fcda5b 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -111,4 +111,28 @@ const struct util_format_description * util_format_description(enum pipe_format format); +void +util_format_read_4f(enum pipe_format format, + float *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4f(enum pipe_format format, + const float *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_read_4ub(enum pipe_format format, + uint8_t *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4ub(enum pipe_format format, + const uint8_t *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + #endif /* ! U_FORMAT_H */ diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py new file mode 100644 index 00000000000..eeb1a9657fd --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_access.py @@ -0,0 +1,498 @@ +#!/usr/bin/env python + +''' +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Pixel format accessor functions. + * + * @author Jose Fonseca + */ +''' + + +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 + + +def is_format_supported(format): + '''Determines whether we actually have the plumbing necessary to generate the + to read/write to/from this format.''' + + # FIXME: Ideally we would support any format combination here. + + # XXX: It should be straightforward to support srgb + if format.colorspace not in ('rgb', 'zs'): + return False + + if format.layout not in (ARITH, ARRAY): + return False + + for i in range(4): + type = format.in_types[i] + if type.kind 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: + return False + + return True + + +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' + 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): + '''Generate the function to read pixels from a particular format''' + + name = short_name(format) + + src_native_type = native_type(format) + + print 'static void' + print 'util_format_%s_read_%s(%s *dst, unsigned dst_stride, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, dst_suffix, dst_native_type) + print '{' + print ' unsigned x, y;' + print ' const uint8_t *src_row = src + y0*src_stride;' + print ' %s *dst_row = dst;' % dst_native_type + print ' for (y = 0; y < h; ++y) {' + print ' const %s *src_pixel = (const %s *)(src_row + x0*%u);' % (src_native_type, src_native_type, format.stride()) + print ' %s *dst_pixel = dst_row;' %dst_native_type + print ' for (x = 0; x < w; ++x) {' + + names = ['']*4 + if format.colorspace == 'rgb': + for i in range(4): + swizzle = format.out_swizzle[i] + if swizzle < 4: + names[swizzle] += 'rgba'[i] + elif format.colorspace == 'zs': + swizzle = format.out_swizzle[0] + if swizzle < 4: + names[swizzle] = 'z' + else: + assert False + 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) + else: + assert False + + for i in range(4): + if format.colorspace == 'rgb': + swizzle = format.out_swizzle[i] + if swizzle < 4: + value = names[swizzle] + elif swizzle == SWIZZLE_0: + value = '0' + elif swizzle == SWIZZLE_1: + value = '1' + else: + assert False + elif format.colorspace == 'zs': + if i < 3: + value = 'z' + else: + value = '1' + 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 ' }' + print '}' + print + + +def generate_format_write(format, src_type, src_native_type, src_suffix): + '''Generate the function to write pixels to a particular format''' + + name = short_name(format) + + dst_native_type = native_type(format) + + print 'static void' + print 'util_format_%s_write_%s(const %s *src, unsigned src_stride, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type) + print '{' + print ' unsigned x, y;' + print ' uint8_t *dst_row = dst + y0*dst_stride;' + print ' const %s *src_row = src;' % src_native_type + print ' for (y = 0; y < h; ++y) {' + print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride()) + 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 + else: + assert False + print ' src_pixel += 4;' + + print ' }' + print ' dst_row += dst_stride;' + print ' src_row += src_stride/sizeof(%s);' % src_native_type + print ' }' + print '}' + print + + +def generate_read(formats, dst_type, 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) + + 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) + print '{' + print ' void (*func)(%s *dst, unsigned dst_stride, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % dst_native_type + print ' switch(format) {' + 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 ' break;' + print ' default:' + print ' debug_printf("unsupported format\\n");' + print ' return;' + print ' }' + print ' func(dst, dst_stride, (const uint8_t *)src, src_stride, x, y, w, h);' + print '}' + print + + +def generate_write(formats, src_type, 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) + + 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) + + print '{' + print ' void (*func)(const %s *src, unsigned src_stride, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % src_native_type + print ' switch(format) {' + 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 ' break;' + print ' default:' + print ' debug_printf("unsupported format\\n");' + print ' return;' + print ' }' + print ' func(src, src_stride, (uint8_t *)dst, dst_stride, x, y, w, h);' + print '}' + print + + +def main(): + formats = [] + for arg in sys.argv[1:]: + formats.extend(parse(arg)) + + print '/* This file is autogenerated by u_format_access.py from u_format.csv. Do not edit directly. */' + print + # This will print the copyright message on the top of this file + print __doc__.strip() + print + print '#include "pipe/p_compiler.h"' + print '#include "u_format.h"' + print '#include "u_math.h"' + print + + generate_clamp() + + type = Type(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) + native_type = 'uint8_t' + suffix = '4ub' + + generate_read(formats, type, native_type, suffix) + generate_write(formats, type, native_type, suffix) + + +if __name__ == '__main__': + main() diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py new file mode 100755 index 00000000000..493aff71127 --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_parse.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +''' +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +''' + + +import sys + + +VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5) + +SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7) + +ARITH = 'arith' +ARRAY = 'array' + + +class Type: + '''Describe the type of a color channel.''' + + def __init__(self, kind, norm, size): + self.kind = kind + self.norm = norm + self.size = size + self.sign = kind in (SIGNED, FIXED, FLOAT) + + def __str__(self): + s = str(self.kind) + if self.norm: + s += 'n' + s += str(self.size) + return s + + def __eq__(self, other): + return self.kind == other.kind and self.norm == other.norm and self.size == other.size + + +class Format: + '''Describe a pixel format.''' + + def __init__(self, name, layout, block_width, block_height, in_types, out_swizzle, colorspace): + self.name = name + self.layout = layout + self.block_width = block_width + self.block_height = block_height + self.in_types = in_types + self.out_swizzle = out_swizzle + self.name = name + self.colorspace = colorspace + + def __str__(self): + return self.name + + def block_size(self): + size = 0 + for type in self.in_types: + size += type.size + return size + + def stride(self): + return self.block_size()/8 + + +_kind_parse_map = { + '': VOID, + 'x': VOID, + 'u': UNSIGNED, + 's': SIGNED, + 'h': FIXED, + 'f': FLOAT, +} + +_swizzle_parse_map = { + 'x': SWIZZLE_X, + 'y': SWIZZLE_Y, + 'z': SWIZZLE_Z, + 'w': SWIZZLE_W, + '0': SWIZZLE_0, + '1': SWIZZLE_1, + '_': SWIZZLE_NONE, +} + +def parse(filename): + '''Parse the format descrition in CSV format in terms of the + Type and Format classes above.''' + + stream = open(filename) + formats = [] + for line in stream: + line = line.rstrip() + fields = [field.strip() for field in line.split(',')] + name = fields[0] + layout = fields[1] + block_width, block_height = map(int, fields[2:4]) + in_types = [] + for field in fields[4:8]: + if field: + kind = _kind_parse_map[field[0]] + if field[1] == 'n': + norm = True + size = int(field[2:]) + else: + norm = False + size = int(field[1:]) + else: + kind = VOID + norm = False + size = 0 + in_type = Type(kind, norm, size) + in_types.append(in_type) + out_swizzle = [_swizzle_parse_map[swizzle] for swizzle in fields[8]] + colorspace = fields[9] + formats.append(Format(name, layout, block_width, block_height, in_types, out_swizzle, colorspace)) + return formats + diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py index c536e39171c..8834568e8ee 100755 --- a/src/gallium/auxiliary/util/u_format_table.py +++ b/src/gallium/auxiliary/util/u_format_table.py @@ -3,7 +3,7 @@ ''' /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -21,7 +21,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,76 +32,7 @@ import sys - -UNSIGNED, SIGNED, FIXED, FLOAT = 'u', 's', 'h', 'f' - - -class Type: - - def __init__(self, kind, norm, size): - self.kind = kind - self.norm = norm - self.size = size - - def __str__(self): - s = str(self.kind) - if norm: - s += 'n' - s += str(self.size) - return s - - -class Format: - - def __init__(self, name, layout, block_width, block_height, in_types, out_swizzle, colorspace): - self.name = name - self.layout = layout - self.block_width = block_width - self.block_height = block_height - self.in_types = in_types - self.out_swizzle = out_swizzle - self.name = name - self.colorspace = colorspace - - def __str__(self): - return self.name - - def block_size(self): - size = 0 - for type in self.in_types: - size += type.size - return size - - -def parse(filename): - stream = open(filename) - formats = [] - for line in stream: - line = line.rstrip() - fields = [field.strip() for field in line.split(',')] - name = fields[0] - layout = fields[1] - block_width, block_height = map(int, fields[2:4]) - in_types = [] - for field in fields[4:8]: - if field: - kind = field[0] - if field[1] == 'n': - norm = True - size = int(field[2:]) - else: - norm = False - size = int(field[1:]) - else: - kind = '' - norm = False - size = 0 - in_type = Type(kind, norm, size) - in_types.append(in_type) - out_swizzle = fields[8] - colorspace = fields[9] - formats.append(Format(name, layout, block_width, block_height, in_types, out_swizzle, colorspace)) - return formats +from u_format_parse import * def layout_map(layout): @@ -122,12 +53,11 @@ colorspace_channels_map = { kind_map = { - '': "UTIL_FORMAT_TYPE_VOID", - 'x': "UTIL_FORMAT_TYPE_VOID", + VOID: "UTIL_FORMAT_TYPE_VOID", UNSIGNED: "UTIL_FORMAT_TYPE_UNSIGNED", - SIGNED: "UTIL_FORMAT_TYPE_SIGNED", - FIXED: "UTIL_FORMAT_TYPE_FIXED", - FLOAT: "UTIL_FORMAT_TYPE_FLOAT", + SIGNED: "UTIL_FORMAT_TYPE_SIGNED", + FIXED: "UTIL_FORMAT_TYPE_FIXED", + FLOAT: "UTIL_FORMAT_TYPE_FLOAT", } @@ -139,13 +69,13 @@ def bool_map(value): swizzle_map = { - 'x': "UTIL_FORMAT_SWIZZLE_X", - 'y': "UTIL_FORMAT_SWIZZLE_Y", - 'z': "UTIL_FORMAT_SWIZZLE_Z", - 'w': "UTIL_FORMAT_SWIZZLE_W", - '0': "UTIL_FORMAT_SWIZZLE_0", - '1': "UTIL_FORMAT_SWIZZLE_1", - '_': "UTIL_FORMAT_SWIZZLE_NONE", + SWIZZLE_X: "UTIL_FORMAT_SWIZZLE_X", + SWIZZLE_Y: "UTIL_FORMAT_SWIZZLE_Y", + SWIZZLE_Z: "UTIL_FORMAT_SWIZZLE_Z", + SWIZZLE_W: "UTIL_FORMAT_SWIZZLE_W", + SWIZZLE_0: "UTIL_FORMAT_SWIZZLE_0", + SWIZZLE_1: "UTIL_FORMAT_SWIZZLE_1", + SWIZZLE_NONE: "UTIL_FORMAT_SWIZZLE_NONE", } -- 2.30.2