summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-08-30 12:02:36 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-08-30 12:37:03 +0100
commit3d305243938980af520c6d3e0ce02f4ee3a6126c (patch)
tree87d04c757ca756195e533100f2b6015fd1189794 /src
parent379304a72cf332e2d570b13663bb447ec7a12940 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/util/.gitignore1
-rw-r--r--src/gallium/auxiliary/util/Makefile6
-rw-r--r--src/gallium/auxiliary/util/SConscript8
-rw-r--r--src/gallium/auxiliary/util/u_format.csv16
-rw-r--r--src/gallium/auxiliary/util/u_format.h24
-rw-r--r--src/gallium/auxiliary/util/u_format_access.py498
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py141
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py98
8 files changed, 699 insertions, 93 deletions
diff --git a/src/gallium/auxiliary/util/.gitignore b/src/gallium/auxiliary/util/.gitignore
index 53fe9b8a65..29c586c9b5 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 77f1133096..ae8d330a78 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 5ceb1970b5..28a5ab4256 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 74bd21a838..00a46d0cc4 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 b5504ebe05..7b5b7fcda5 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 0000000000..eeb1a9657f
--- /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 <jfonseca@vmware.com>
+ */
+'''
+
+
+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 0000000000..493aff7112
--- /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 c536e39171..8834568e8e 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",
}