summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/.gitignore1
-rw-r--r--src/gallium/auxiliary/util/u_format.c45
-rw-r--r--src/gallium/auxiliary/util/u_format.csv308
-rw-r--r--src/gallium/auxiliary/util/u_format.h136
-rw-r--r--src/gallium/auxiliary/util/u_format_access.py358
-rw-r--r--src/gallium/auxiliary/util/u_format_pack.py484
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py198
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py80
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h5
-rw-r--r--src/gallium/auxiliary/util/u_math.h11
10 files changed, 1080 insertions, 546 deletions
diff --git a/src/gallium/auxiliary/util/.gitignore b/src/gallium/auxiliary/util/.gitignore
index 29c586c9b5..448d2f304f 100644
--- a/src/gallium/auxiliary/util/.gitignore
+++ b/src/gallium/auxiliary/util/.gitignore
@@ -1,2 +1,3 @@
u_format_access.c
u_format_table.c
+u_format_pack.h
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
deleted file mode 100644
index e0724a1a8b..0000000000
--- a/src/gallium/auxiliary/util/u_format.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-
-#include "u_format.h"
-
-
-const struct util_format_description *
-util_format_description(enum pipe_format format)
-{
- const struct util_format_description *desc;
-
- if (format >= PIPE_FORMAT_COUNT) {
- return NULL;
- }
-
- desc = &util_format_description_table[format];
- assert(desc->format == format);
-
- return desc;
-}
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 01f7931aed..a7bd6abf81 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -1,109 +1,199 @@
-PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb
-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_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 , 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_YCBCR , yuv , 2, 1, x32 , , , , xyz1, yuv
-PIPE_FORMAT_YCBCR_REV , yuv , 2, 1, x32 , , , , xyz1, yuv
-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, un24, un8 , , , xy__, zs
-PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs
-PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un24, un8 , , , x___, zs
-PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un8 , un24, , , y___, 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
-PIPE_FORMAT_R64G64B64A64_FLOAT , array , 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
-PIPE_FORMAT_R32_FLOAT , array , 1, 1, f32 , , , , x001, rgb
-PIPE_FORMAT_R32G32_FLOAT , array , 1, 1, f32 , f32 , , , xy01, rgb
-PIPE_FORMAT_R32G32B32_FLOAT , array , 1, 1, f32 , f32 , f32 , , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_FLOAT , array , 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb
-PIPE_FORMAT_R32_UNORM , array , 1, 1, un32, , , , x001, rgb
-PIPE_FORMAT_R32G32_UNORM , array , 1, 1, un32, un32, , , xy01, rgb
-PIPE_FORMAT_R32G32B32_UNORM , array , 1, 1, un32, un32, un32, , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_UNORM , array , 1, 1, un32, un32, un32, un32, xyzw, rgb
-PIPE_FORMAT_R32_USCALED , array , 1, 1, u32 , , , , x001, rgb
-PIPE_FORMAT_R32G32_USCALED , array , 1, 1, u32 , u32 , , , xy01, rgb
-PIPE_FORMAT_R32G32B32_USCALED , array , 1, 1, u32 , u32 , u32 , , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_USCALED , array , 1, 1, u32 , u32 , u32 , u32 , xyzw, rgb
-PIPE_FORMAT_R32_SNORM , array , 1, 1, sn32, , , , x001, rgb
-PIPE_FORMAT_R32G32_SNORM , array , 1, 1, sn32, sn32, , , xy01, rgb
-PIPE_FORMAT_R32G32B32_SNORM , array , 1, 1, sn32, sn32, sn32, , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_SNORM , array , 1, 1, sn32, sn32, sn32, sn32, xyzw, rgb
-PIPE_FORMAT_R32_SSCALED , array , 1, 1, s32 , , , , x001, rgb
-PIPE_FORMAT_R32G32_SSCALED , array , 1, 1, s32 , s32 , , , xy01, rgb
-PIPE_FORMAT_R32G32B32_SSCALED , array , 1, 1, s32 , s32 , s32 , , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_SSCALED , array , 1, 1, s32 , s32 , s32 , s32 , xyzw, rgb
-PIPE_FORMAT_R16_UNORM , array , 1, 1, un16, , , , x001, rgb
-PIPE_FORMAT_R16G16_UNORM , array , 1, 1, un16, un16, , , xy01, rgb
-PIPE_FORMAT_R16G16B16_UNORM , array , 1, 1, un16, un16, un16, , xyz1, rgb
-PIPE_FORMAT_R16G16B16A16_UNORM , array , 1, 1, un16, un16, un16, un16, xyzw, rgb
-PIPE_FORMAT_R16_USCALED , array , 1, 1, u16 , , , , x001, rgb
-PIPE_FORMAT_R16G16_USCALED , array , 1, 1, u16 , u16 , , , xy01, rgb
-PIPE_FORMAT_R16G16B16_USCALED , array , 1, 1, u16 , u16 , u16 , , xyz1, rgb
-PIPE_FORMAT_R16G16B16A16_USCALED , array , 1, 1, u16 , u16 , u16 , u16 , xyzw, rgb
-PIPE_FORMAT_R16_SNORM , array , 1, 1, sn16, , , , x001, rgb
-PIPE_FORMAT_R16G16_SNORM , array , 1, 1, sn16, sn16, , , xy01, rgb
-PIPE_FORMAT_R16G16B16_SNORM , array , 1, 1, sn16, sn16, sn16, , xyz1, rgb
-PIPE_FORMAT_R16G16B16A16_SNORM , array , 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb
-PIPE_FORMAT_R16_SSCALED , array , 1, 1, s16 , , , , x001, rgb
-PIPE_FORMAT_R16G16_SSCALED , array , 1, 1, s16 , s16 , , , xy01, rgb
-PIPE_FORMAT_R16G16B16_SSCALED , array , 1, 1, s16 , s16 , s16 , , xyz1, rgb
-PIPE_FORMAT_R16G16B16A16_SSCALED , array , 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb
-PIPE_FORMAT_R8_UNORM , array , 1, 1, un8 , , , , x001, rgb
-PIPE_FORMAT_R8G8_UNORM , array , 1, 1, un8 , un8 , , , yx01, rgb
-PIPE_FORMAT_R8G8B8_UNORM , array , 1, 1, un8 , un8 , un8 , , zyx1, rgb
-PIPE_FORMAT_R8G8B8A8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb
-PIPE_FORMAT_R8G8B8X8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb
-PIPE_FORMAT_R8_USCALED , array , 1, 1, u8 , , , , x001, rgb
-PIPE_FORMAT_R8G8_USCALED , array , 1, 1, u8 , u8 , , , xy01, rgb
-PIPE_FORMAT_R8G8B8_USCALED , array , 1, 1, u8 , u8 , u8 , , xyz1, rgb
-PIPE_FORMAT_R8G8B8A8_USCALED , array , 1, 1, u8 , u8 , u8 , u8 , xyzw, rgb
-PIPE_FORMAT_R8G8B8X8_USCALED , array , 1, 1, u8 , u8 , u8 , u8 , xyz1, rgb
-PIPE_FORMAT_R8_SNORM , array , 1, 1, sn8 , , , , x001, rgb
-PIPE_FORMAT_R8G8_SNORM , array , 1, 1, sn8 , sn8 , , , xy01, rgb
-PIPE_FORMAT_R8G8B8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
-PIPE_FORMAT_R8G8B8A8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
-PIPE_FORMAT_R8G8B8X8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyz1, rgb
-PIPE_FORMAT_B6G5R5_SNORM , arith , 1, 1, sn5 , sn5 , sn6 , , xyz1, rgb
-PIPE_FORMAT_A8B8G8R8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzyx, rgb
-PIPE_FORMAT_X8B8G8R8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzy1, rgb
-PIPE_FORMAT_R8_SSCALED , array , 1, 1, s8 , , , , x001, rgb
-PIPE_FORMAT_R8G8_SSCALED , array , 1, 1, s8 , s8 , , , xy01, rgb
-PIPE_FORMAT_R8G8B8_SSCALED , array , 1, 1, s8 , s8 , s8 , , xyz1, rgb
-PIPE_FORMAT_R8G8B8A8_SSCALED , array , 1, 1, s8 , s8 , s8 , s8 , xyzw, rgb
-PIPE_FORMAT_R8G8B8X8_SSCALED , array , 1, 1, s8 , s8 , s8 , s8 , xyz1, rgb
-PIPE_FORMAT_R32_FIXED , array , 1, 1, h32 , , , , x001, rgb
-PIPE_FORMAT_R32G32_FIXED , array , 1, 1, h32 , h32 , , , xy01, rgb
-PIPE_FORMAT_R32G32B32_FIXED , array , 1, 1, h32 , h32 , h32 , , xyz1, rgb
-PIPE_FORMAT_R32G32B32A32_FIXED , array , 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb
-PIPE_FORMAT_L8_SRGB , arith , 1, 1, u8 , , , , xxx1, srgb
-PIPE_FORMAT_A8L8_SRGB , arith , 1, 1, u8 , u8 , , , xxxy, srgb
-PIPE_FORMAT_R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , , xyz1, srgb
-PIPE_FORMAT_R8G8B8A8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , xyzw, srgb
-PIPE_FORMAT_R8G8B8X8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , xyz1, srgb
-PIPE_FORMAT_A8R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , yzwx, srgb
-PIPE_FORMAT_X8R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , yzw1, srgb
-PIPE_FORMAT_B8G8R8A8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , zyxw, srgb
-PIPE_FORMAT_B8G8R8X8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb
-PIPE_FORMAT_X8UB8UG8SR8S_NORM , array , 1, 1, sn8 , sn8 , un8 , x8 , wzy1, rgb
-PIPE_FORMAT_B6UG5SR5S_NORM , arith , 1, 1, sn5 , sn5 , un6 , , xyz1, rgb
-PIPE_FORMAT_DXT1_RGB , dxt , 4, 4, x64 , , , , xyz1, rgb
-PIPE_FORMAT_DXT1_RGBA , dxt , 4, 4, x64 , , , , xyzw, rgb
-PIPE_FORMAT_DXT3_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT5_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT1_SRGB , dxt , 4, 4, x64 , , , , xyz1, srgb
-PIPE_FORMAT_DXT1_SRGBA , dxt , 4, 4, x64 , , , , xyzw, srgb
-PIPE_FORMAT_DXT3_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb
-PIPE_FORMAT_DXT5_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb
+###########################################################################
+#
+# Copyright 2009-2010 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 THE AUTHORS 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.
+#
+###########################################################################
+
+# This CSV file has the input data for u_format.h's struct
+# util_format_description.
+#
+# Each format entry contains:
+# - name, per enum pipe_format
+# - layout, per enum util_format_layout, in shortened lower caps
+# - pixel block's width
+# - pixel block's height
+# - channel encoding (only meaningful for plain layout), containing for each
+# channel the following information:
+# - type, one of
+# - 'x': void
+# - 'u': unsigned
+# - 's': signed
+# - 'h': fixed
+# - 'f': FLOAT
+# - optionally followed by 'n' if it is normalized
+# - number of bits
+# - channel swizzle
+# - color space: rgb, yub, sz
+#
+# See also:
+# - http://msdn.microsoft.com/en-us/library/ee416489.aspx
+# - http://msdn.microsoft.com/en-us/library/ee415668.aspx
+#
+# Note that GL doesn't really specify the layout of internal formats. See
+# OpenGL 2.1 specification, Table 3.16, on the "Correspondence of sized
+# internal formats to base in- ternal formats, and desired component
+# resolutions for each sized internal format."
+
+# Typical rendertarget formats
+PIPE_FORMAT_A8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb
+PIPE_FORMAT_X8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , zyx1, rgb
+PIPE_FORMAT_B8G8R8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb
+PIPE_FORMAT_B8G8R8X8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb
+PIPE_FORMAT_R8G8B8X8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb
+# XXX: insert PIPE_FORMAT_R8G8B8A8_UNORM here later
+# XXX: insert PIPE_FORMAT_R8G8B8_UNORM here later
+PIPE_FORMAT_A1R5G5B5_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
+PIPE_FORMAT_A4R4G4B4_UNORM , plain, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb
+PIPE_FORMAT_R5G6B5_UNORM , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb
+PIPE_FORMAT_A2B10G10R10_UNORM , plain, 1, 1, un10, un10, un10, un2 , xyzw, rgb
+
+# Luminance/Intensity/Alpha formats
+PIPE_FORMAT_L8_UNORM , plain, 1, 1, un8 , , , , xxx1, rgb
+PIPE_FORMAT_A8_UNORM , plain, 1, 1, un8 , , , , 000x, rgb
+PIPE_FORMAT_I8_UNORM , plain, 1, 1, un8 , , , , xxxx, rgb
+PIPE_FORMAT_A8L8_UNORM , plain, 1, 1, un8 , un8 , , , xxxy, rgb
+PIPE_FORMAT_L16_UNORM , plain, 1, 1, un16, , , , xxx1, rgb
+
+# SRGB formats
+PIPE_FORMAT_L8_SRGB , plain, 1, 1, un8 , , , , xxx1, srgb
+PIPE_FORMAT_A8L8_SRGB , plain, 1, 1, un8 , un8 , , , xxxy, srgb
+PIPE_FORMAT_R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , , zyx1, srgb
+PIPE_FORMAT_R8G8B8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, srgb
+PIPE_FORMAT_R8G8B8X8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , wzy1, srgb
+PIPE_FORMAT_A8R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, srgb
+PIPE_FORMAT_X8R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , zyx1, srgb
+PIPE_FORMAT_B8G8R8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, srgb
+PIPE_FORMAT_B8G8R8X8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , yzw1, srgb
+
+# Signed formats (typically used for bump map textures)
+PIPE_FORMAT_A8B8G8R8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
+PIPE_FORMAT_X8B8G8R8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyz1, rgb
+PIPE_FORMAT_X8UB8UG8SR8S_NORM , plain, 1, 1, sn8 , sn8 , un8 , x8 , xyz1, rgb
+PIPE_FORMAT_B6UG5SR5S_NORM , plain, 1, 1, sn5 , sn5 , un6 , , xyz1, rgb
+
+# Depth-stencil formats
+PIPE_FORMAT_S8_UNORM , plain, 1, 1, un8 , , , , _x__, zs
+PIPE_FORMAT_Z16_UNORM , plain, 1, 1, un16, , , , x___, zs
+PIPE_FORMAT_Z32_UNORM , plain, 1, 1, un32, , , , x___, zs
+PIPE_FORMAT_Z32_FLOAT , plain, 1, 1, f32 , , , , x___, zs
+PIPE_FORMAT_S8Z24_UNORM , plain, 1, 1, un24, un8 , , , xy__, zs
+PIPE_FORMAT_Z24S8_UNORM , plain, 1, 1, un8 , un24, , , yx__, zs
+PIPE_FORMAT_X8Z24_UNORM , plain, 1, 1, un24, un8 , , , x___, zs
+PIPE_FORMAT_Z24X8_UNORM , plain, 1, 1, un8 , un24, , , y___, zs
+
+# YUV formats
+# http://www.fourcc.org/yuv.php#UYVY
+PIPE_FORMAT_YCBCR , subsampled, 2, 1, x32 , , , , xyz1, yuv
+# http://www.fourcc.org/yuv.php#YUYV (a.k.a http://www.fourcc.org/yuv.php#YUY2)
+# XXX: u_tile.c's ycbcr_get_tile_rgba actually interprets it as VYUY but the
+# intent should be to match D3DFMT_YUY2
+PIPE_FORMAT_YCBCR_REV , subsampled, 2, 1, x32 , , , , xyz1, yuv
+
+# Compressed formats
+PIPE_FORMAT_DXT1_RGB , compressed, 4, 4, x64 , , , , xyz1, rgb
+PIPE_FORMAT_DXT1_RGBA , compressed, 4, 4, x64 , , , , xyzw, rgb
+PIPE_FORMAT_DXT3_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT5_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT1_SRGB , compressed, 4, 4, x64 , , , , xyz1, srgb
+PIPE_FORMAT_DXT1_SRGBA , compressed, 4, 4, x64 , , , , xyzw, srgb
+PIPE_FORMAT_DXT3_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
+PIPE_FORMAT_DXT5_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
+
+# Old vector formats
+# XXX: Swizzle notation is reversed for these!
+# See also:
+# - src/gallium/auxiliary/translate/translate_generic.c
+# - src/mesa/state_tracker/st_draw.c
+PIPE_FORMAT_R64_FLOAT , plain, 1, 1, f64 , , , , x001, rgb
+PIPE_FORMAT_R64G64_FLOAT , plain, 1, 1, f64 , f64 , , , xy01, rgb
+PIPE_FORMAT_R64G64B64_FLOAT , plain, 1, 1, f64 , f64 , f64 , , xyz1, rgb
+PIPE_FORMAT_R64G64B64A64_FLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
+PIPE_FORMAT_R32_FLOAT , plain, 1, 1, f32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_FLOAT , plain, 1, 1, f32 , f32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_FLOAT , plain, 1, 1, f32 , f32 , f32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_FLOAT , plain, 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb
+PIPE_FORMAT_R32_UNORM , plain, 1, 1, un32, , , , x001, rgb
+PIPE_FORMAT_R32G32_UNORM , plain, 1, 1, un32, un32, , , xy01, rgb
+PIPE_FORMAT_R32G32B32_UNORM , plain, 1, 1, un32, un32, un32, , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_UNORM , plain, 1, 1, un32, un32, un32, un32, xyzw, rgb
+PIPE_FORMAT_R32_USCALED , plain, 1, 1, u32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_USCALED , plain, 1, 1, u32 , u32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_USCALED , plain, 1, 1, u32 , u32 , u32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_USCALED , plain, 1, 1, u32 , u32 , u32 , u32 , xyzw, rgb
+PIPE_FORMAT_R32_SNORM , plain, 1, 1, sn32, , , , x001, rgb
+PIPE_FORMAT_R32G32_SNORM , plain, 1, 1, sn32, sn32, , , xy01, rgb
+PIPE_FORMAT_R32G32B32_SNORM , plain, 1, 1, sn32, sn32, sn32, , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_SNORM , plain, 1, 1, sn32, sn32, sn32, sn32, xyzw, rgb
+PIPE_FORMAT_R32_SSCALED , plain, 1, 1, s32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_SSCALED , plain, 1, 1, s32 , s32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_SSCALED , plain, 1, 1, s32 , s32 , s32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_SSCALED , plain, 1, 1, s32 , s32 , s32 , s32 , xyzw, rgb
+PIPE_FORMAT_R32_FIXED , plain, 1, 1, h32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_FIXED , plain, 1, 1, h32 , h32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_FIXED , plain, 1, 1, h32 , h32 , h32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_FIXED , plain, 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb
+PIPE_FORMAT_R16_UNORM , plain, 1, 1, un16, , , , x001, rgb
+PIPE_FORMAT_R16G16_UNORM , plain, 1, 1, un16, un16, , , xy01, rgb
+PIPE_FORMAT_R16G16B16_UNORM , plain, 1, 1, un16, un16, un16, , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_UNORM , plain, 1, 1, un16, un16, un16, un16, xyzw, rgb
+PIPE_FORMAT_R16_USCALED , plain, 1, 1, u16 , , , , x001, rgb
+PIPE_FORMAT_R16G16_USCALED , plain, 1, 1, u16 , u16 , , , xy01, rgb
+PIPE_FORMAT_R16G16B16_USCALED , plain, 1, 1, u16 , u16 , u16 , , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_USCALED , plain, 1, 1, u16 , u16 , u16 , u16 , xyzw, rgb
+PIPE_FORMAT_R16_SNORM , plain, 1, 1, sn16, , , , x001, rgb
+PIPE_FORMAT_R16G16_SNORM , plain, 1, 1, sn16, sn16, , , xy01, rgb
+PIPE_FORMAT_R16G16B16_SNORM , plain, 1, 1, sn16, sn16, sn16, , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_SNORM , plain, 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb
+PIPE_FORMAT_R16_SSCALED , plain, 1, 1, s16 , , , , x001, rgb
+PIPE_FORMAT_R16G16_SSCALED , plain, 1, 1, s16 , s16 , , , xy01, rgb
+PIPE_FORMAT_R16G16B16_SSCALED , plain, 1, 1, s16 , s16 , s16 , , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_SSCALED , plain, 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb
+PIPE_FORMAT_R8_UNORM , plain, 1, 1, un8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_UNORM , plain, 1, 1, un8 , un8 , , , xy01, rgb
+# XXX: insert PIPE_FORMAT_R8G8B8_UNORM here later
+# XXX: insert PIPE_FORMAT_R8G8B8A8_UNORM here later
+PIPE_FORMAT_R8_USCALED , plain, 1, 1, u8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_USCALED , plain, 1, 1, u8 , u8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_USCALED , plain, 1, 1, u8 , u8 , u8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_USCALED , plain, 1, 1, u8 , u8 , u8 , u8 , xyzw, rgb
+PIPE_FORMAT_R8_SNORM , plain, 1, 1, sn8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_SNORM , plain, 1, 1, sn8 , sn8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
+PIPE_FORMAT_R8_SSCALED , plain, 1, 1, s8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_SSCALED , plain, 1, 1, s8 , s8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_SSCALED , plain, 1, 1, s8 , s8 , s8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_SSCALED , plain, 1, 1, s8 , s8 , s8 , s8 , xyzw, rgb
+
+# Ambiguous formats
+# FIXME: They are used with different meanings in different places!!!
+PIPE_FORMAT_R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , , zyx1, rgb
+PIPE_FORMAT_R8G8B8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb
+
+# Unused formats
+# XXX: Couldn't find any state tracker using them!!
+PIPE_FORMAT_B6G5R5_SNORM , plain, 1, 1, sn5 , sn5 , sn6 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8X8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , wzy1, rgb
+PIPE_FORMAT_R8G8B8X8_USCALED , plain, 1, 1, u8 , u8 , u8 , u8 , wzy1, rgb
+PIPE_FORMAT_R8G8B8X8_SSCALED , plain, 1, 1, s8 , s8 , s8 , s8 , wzy1, rgb
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 2fbbb83d4b..e8fa0022b5 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2009 Vmware, Inc.
+ * Copyright 2009-2010 Vmware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -39,47 +39,32 @@ extern "C" {
/**
- * Describe how to best pack/unpack pixels into/from the prescribed format.
+ * Describe how to pack/unpack pixels into/from the prescribed format.
*
- * These are used for automatic code generation of pixel packing and unpacking
- * routines (in compile time, e.g., u_format_access.py, or in runtime, like
- * llvmpipe does).
- *
- * Thumb rule is: if you're not code generating pixel packing/unpacking then
- * these are irrelevant for you.
- *
- * Note that this can be deduced from other values in util_format_description
- * structure. This is by design, to make code generation of pixel
- * packing/unpacking/sampling routines simple and efficient.
- *
- * XXX: This should be renamed to something like util_format_pack.
+ * XXX: This could be renamed to something like util_format_pack, or broke down
+ * in flags inside util_format_block that said exactly what we want.
*/
enum util_format_layout {
/**
- * Single scalar component.
+ * Formats with util_format_block::width == util_format_block::height == 1
+ * that can be described as an ordinary data structure.
*/
- UTIL_FORMAT_LAYOUT_SCALAR = 0,
+ UTIL_FORMAT_LAYOUT_PLAIN = 0,
/**
- * One or more components of mixed integer formats, arithmetically encoded
- * in a word up to 32bits.
+ * Formats with sub-sampled channels.
+ *
+ * This is for formats like YV12 where there is less than one sample per
+ * pixel.
+ *
+ * XXX: This could actually b
*/
- UTIL_FORMAT_LAYOUT_ARITH = 1,
+ UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
/**
- * One or more components, no mixed formats, each with equal power of two
- * number of bytes.
+ * An unspecified compression algorithm.
*/
- UTIL_FORMAT_LAYOUT_ARRAY = 2,
-
- /**
- * XXX: Not used yet. These might go away and be replaced by a single entry,
- * for formats where multiple pixels have to be
- * read in order to determine a single pixel value (i.e., block.width > 1
- * || block.height > 1)
- */
- UTIL_FORMAT_LAYOUT_YUV = 3,
- UTIL_FORMAT_LAYOUT_DXT = 4
+ UTIL_FORMAT_LAYOUT_COMPRESSED = 4
};
@@ -136,10 +121,50 @@ struct util_format_description
{
enum pipe_format format;
const char *name;
+
+ /**
+ * Pixel block dimensions.
+ */
struct util_format_block block;
+
enum util_format_layout layout;
+
+ /**
+ * The number of channels.
+ */
+ unsigned nr_channels:3;
+
+ /**
+ * Whether all channels have the same number of (whole) bytes.
+ */
+ unsigned is_array:1;
+
+ /**
+ * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
+ */
+ unsigned is_mixed:1;
+
+ /**
+ * Input channel description.
+ *
+ * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
+ */
struct util_format_channel_description channel[4];
+
+ /**
+ * Output channel swizzle.
+ *
+ * The order is either:
+ * - RGBA
+ * - YUV(A)
+ * - ZS
+ * depending on the colorspace.
+ */
unsigned char swizzle[4];
+
+ /**
+ * Colorspace transformation.
+ */
enum util_format_colorspace colorspace;
};
@@ -179,7 +204,7 @@ util_format_is_compressed(enum pipe_format format)
return FALSE;
}
- return desc->layout == UTIL_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
+ return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE;
}
static INLINE boolean
@@ -253,14 +278,7 @@ util_format_get_blockwidth(enum pipe_format format)
return 1;
}
- switch (desc->layout) {
- case UTIL_FORMAT_LAYOUT_YUV:
- return 2;
- case UTIL_FORMAT_LAYOUT_DXT:
- return 4;
- default:
- return 1;
- }
+ return desc->block.width;
}
static INLINE uint
@@ -273,12 +291,7 @@ util_format_get_blockheight(enum pipe_format format)
return 1;
}
- switch (desc->layout) {
- case UTIL_FORMAT_LAYOUT_DXT:
- return 4;
- default:
- return 1;
- }
+ return desc->block.height;
}
static INLINE unsigned
@@ -373,31 +386,14 @@ util_format_has_alpha(enum pipe_format format)
return FALSE;
}
- switch (desc->layout) {
- case UTIL_FORMAT_LAYOUT_SCALAR:
- case UTIL_FORMAT_LAYOUT_ARITH:
- case UTIL_FORMAT_LAYOUT_ARRAY:
- /* FIXME: pf_get_component_bits( PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_COMP_A ) should not return 0 right? */
- if (format == PIPE_FORMAT_A8_UNORM ||
- format == PIPE_FORMAT_A8L8_UNORM ||
- format == PIPE_FORMAT_A8L8_SRGB) {
- return TRUE;
- }
- return util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) != 0;
- case UTIL_FORMAT_LAYOUT_YUV:
+ switch (desc->colorspace) {
+ case UTIL_FORMAT_COLORSPACE_RGB:
+ case UTIL_FORMAT_COLORSPACE_SRGB:
+ return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
+ case UTIL_FORMAT_COLORSPACE_YUV:
+ return FALSE;
+ case UTIL_FORMAT_COLORSPACE_ZS:
return FALSE;
- case UTIL_FORMAT_LAYOUT_DXT:
- switch (format) {
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- case PIPE_FORMAT_DXT1_SRGBA:
- case PIPE_FORMAT_DXT3_SRGBA:
- case PIPE_FORMAT_DXT5_SRGBA:
- return TRUE;
- default:
- return FALSE;
- }
default:
assert(0);
return FALSE;
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'
diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py
new file mode 100644
index 0000000000..3f33f7cc02
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_pack.py
@@ -0,0 +1,484 @@
+#!/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 packing and unpacking functions.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+'''
+
+
+import sys
+
+from u_format_parse import *
+
+
+def generate_format_type(format):
+ '''Generate a structure that describes the format.'''
+
+ print 'union util_format_%s {' % format.short_name()
+ if format.is_bitmask():
+ print ' uint%u_t value;' % (format.block_size(),)
+ print ' struct {'
+ for channel in format.channels:
+ if format.is_bitmask() and not format.is_array():
+ if channel.type == VOID:
+ if channel.size:
+ print ' unsigned %s:%u;' % (channel.name, channel.size)
+ elif channel.type == UNSIGNED:
+ print ' unsigned %s:%u;' % (channel.name, channel.size)
+ elif channel.type == SIGNED:
+ print ' int %s:%u;' % (channel.name, channel.size)
+ else:
+ assert 0
+ else:
+ assert channel.size % 8 == 0 and is_pot(channel.size)
+ if channel.type == VOID:
+ if channel.size:
+ print ' uint%u_t %s;' % (channel.size, channel.name)
+ elif channel.type == UNSIGNED:
+ print ' uint%u_t %s;' % (channel.size, channel.name)
+ elif channel.type in (SIGNED, FIXED):
+ print ' int%u_t %s;' % (channel.size, channel.name)
+ elif channel.type == FLOAT:
+ if channel.size == 64:
+ print ' double %s;' % (channel.name)
+ elif channel.size == 32:
+ print ' float %s;' % (channel.name)
+ elif channel.size == 16:
+ print ' uint16_t %s;' % (channel.name)
+ else:
+ assert 0
+ else:
+ assert 0
+ print ' } chan;'
+ print '};'
+ print
+
+
+def bswap_format(format):
+ '''Generate a structure that describes the format.'''
+
+ if format.is_bitmask() and not format.is_array():
+ print '#ifdef PIPE_ARCH_BIG_ENDIAN'
+ print ' pixel.value = util_bswap%u(pixel.value);' % format.block_size()
+ print '#endif'
+
+
+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.
+
+ if format.layout != PLAIN:
+ return False
+
+ for i in range(4):
+ channel = format.channels[i]
+ if channel.type not in (VOID, UNSIGNED, SIGNED, 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.swizzles[0] == SWIZZLE_NONE:
+ return False
+
+ return True
+
+
+def native_type(format):
+ '''Get the native appropriate for a format.'''
+
+ 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
+ type = format.channels[0]
+ if type.type == UNSIGNED:
+ return 'uint%u_t' % type.size
+ elif type.type == SIGNED:
+ return 'int%u_t' % type.size
+ elif type.type == 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.type == 'FLOAT':
+ assert False
+ if not type.norm:
+ return 0
+ if type.type == UNSIGNED:
+ return type.size
+ if type.type == SIGNED:
+ return type.size - 1
+ if type.type == FIXED:
+ return type.size / 2
+ assert False
+
+
+def get_one(type):
+ '''Get the value of unity for this type.'''
+ if type.type == '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_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
+
+ src_min = src_channel.min()
+ src_max = src_channel.max()
+ dst_min = dst_channel.min()
+ dst_max = dst_channel.max()
+
+ if src_min < dst_min and src_max > dst_max:
+ return 'CLAMP(%s, %s, %s)' % (value, dst_min, dst_max)
+
+ if src_max > dst_max:
+ return 'MIN2(%s, %s)' % (value, dst_max)
+
+ if src_min < dst_min:
+ return 'MAX2(%s, %s)' % (value, dst_min)
+
+ return value
+
+
+def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True):
+ '''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)
+
+ if clamp:
+ 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 not src_channel.norm and not dst_channel.norm:
+ # neither is normalized -- just cast
+ return '(%s)%s' % (dst_native_type, value)
+
+ if src_channel.type in (SIGNED, UNSIGNED) and dst_channel.type in (SIGNED, UNSIGNED):
+ src_one = get_one(src_channel)
+ dst_one = get_one(dst_channel)
+
+ if src_one > dst_one and src_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_unpack(format, dst_channel, dst_native_type, dst_suffix):
+ '''Generate the function to unpack pixels from a particular format'''
+
+ name = format.short_name()
+
+ src_native_type = native_type(format)
+
+ print 'static INLINE void'
+ print 'util_format_%s_unpack_%s(%s *dst, const void *src)' % (name, dst_suffix, dst_native_type)
+ print '{'
+ print ' union util_format_%s pixel;' % format.short_name()
+ print ' memcpy(&pixel, src, sizeof pixel);'
+ bswap_format(format)
+
+ assert format.layout == PLAIN
+
+ for i in range(4):
+ swizzle = format.swizzles[i]
+ if swizzle < 4:
+ src_channel = format.channels[swizzle]
+ value = 'pixel.chan.%s' % src_channel.name
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
+ value = get_one(dst_channel)
+ elif swizzle == SWIZZLE_NONE:
+ value = '0'
+ else:
+ assert False
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = 'dst[0]'
+ print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
+
+ print '}'
+ print
+
+
+def generate_format_pack(format, src_channel, src_native_type, src_suffix):
+ '''Generate the function to pack pixels to a particular format'''
+
+ name = format.short_name()
+
+ dst_native_type = native_type(format)
+
+ print 'static INLINE void'
+ print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
+ print '{'
+ print ' union util_format_%s pixel;' % format.short_name()
+
+ assert format.layout == PLAIN
+
+ inv_swizzle = format.inv_swizzles()
+
+ for i in range(4):
+ dst_channel = format.channels[i]
+ width = dst_channel.size
+ if inv_swizzle[i] is None:
+ continue
+ value = 'rgba'[inv_swizzle[i]]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = '0'
+ print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
+
+ bswap_format(format)
+ print ' memcpy(dst, &pixel, sizeof pixel);'
+ print '}'
+ print
+
+
+def generate_unpack(formats, dst_channel, dst_native_type, dst_suffix):
+ '''Generate the dispatch function to unpack pixels from any format'''
+
+ for format in formats:
+ if is_format_supported(format):
+ generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix)
+
+ print 'static INLINE void'
+ print 'util_format_unpack_%s(enum pipe_format format, %s *dst, const void *src)' % (dst_suffix, dst_native_type)
+ print '{'
+ print ' void (*func)(%s *dst, const void *src);' % 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_unpack_%s;' % (format.short_name(), dst_suffix)
+ print ' break;'
+ print ' default:'
+ print ' debug_printf("unsupported format\\n");'
+ print ' return;'
+ print ' }'
+ print ' func(dst, src);'
+ print '}'
+ print
+
+
+def generate_pack(formats, src_channel, src_native_type, src_suffix):
+ '''Generate the dispatch function to pack pixels to any format'''
+
+ for format in formats:
+ if is_format_supported(format):
+ generate_format_pack(format, src_channel, src_native_type, src_suffix)
+
+ print 'static INLINE void'
+ print 'util_format_pack_%s(enum pipe_format format, void *dst, %s r, %s g, %s b, %s a)' % (src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
+ print '{'
+ print ' void (*func)(void *dst, %s r, %s g, %s b, %s a);' % (src_native_type, src_native_type, src_native_type, 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_pack_%s;' % (format.short_name(), src_suffix)
+ print ' break;'
+ print ' default:'
+ print ' debug_printf("%s: unsupported format\\n", __FUNCTION__);'
+ print ' return;'
+ print ' }'
+ print ' func(dst, r, g, b, a);'
+ print '}'
+ print
+
+
+def main():
+ formats = []
+ for arg in sys.argv[1:]:
+ formats.extend(parse(arg))
+
+ print '/* This file is autogenerated by u_format_pack.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 '#ifndef U_FORMAT_PACK_H'
+ print '#define U_FORMAT_PACK_H'
+ print
+ print '#include "pipe/p_compiler.h"'
+ print '#include "u_math.h"'
+ print '#include "u_format.h"'
+ print
+
+ generate_clamp()
+
+ for format in formats:
+ if format.layout == PLAIN:
+ generate_format_type(format)
+
+ channel = Channel(FLOAT, False, 32)
+ native_type = 'float'
+ suffix = '4f'
+
+ generate_unpack(formats, channel, native_type, suffix)
+ generate_pack(formats, channel, native_type, suffix)
+
+ channel = Channel(UNSIGNED, True, 8)
+ native_type = 'uint8_t'
+ suffix = '4ub'
+
+ generate_unpack(formats, channel, native_type, suffix)
+ generate_pack(formats, channel, native_type, suffix)
+
+ print
+ print '#ifdef __cplusplus'
+ print '}'
+ print '#endif'
+ print
+ print '#endif /* ! U_FORMAT_PACK_H */'
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
index 493aff7112..250926418e 100755
--- a/src/gallium/auxiliary/util/u_format_parse.py
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -30,64 +30,169 @@
'''
-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'
+PLAIN = 'plain'
+
+RGB = 'rgb'
+SRGB = 'srgb'
+YUV = 'yuv'
+ZS = 'zs'
+
+def is_pot(x):
+ return (x & (x - 1)) == 0;
-class Type:
- '''Describe the type of a color channel.'''
+
+VERY_LARGE = 99999999999999999999999
+
+
+class Channel:
+ '''Describe the channel of a color channel.'''
- def __init__(self, kind, norm, size):
- self.kind = kind
+ def __init__(self, type, norm, size, name = ''):
+ self.type = type
self.norm = norm
self.size = size
- self.sign = kind in (SIGNED, FIXED, FLOAT)
+ self.sign = type in (SIGNED, FIXED, FLOAT)
+ self.name = name
def __str__(self):
- s = str(self.kind)
+ s = str(self.type)
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
+ 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.'''
- def __init__(self, name, layout, block_width, block_height, in_types, out_swizzle, colorspace):
+ def __init__(self, name, layout, block_width, block_height, channels, swizzles, 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.channels = channels
+ self.swizzles = swizzles
self.name = name
self.colorspace = colorspace
def __str__(self):
return self.name
+ def short_name(self):
+ '''Make up a short norm for a format, suitable to be used as suffix in
+ function names.'''
+
+ name = self.name
+ if name.startswith('PIPE_FORMAT_'):
+ name = name[len('PIPE_FORMAT_'):]
+ name = name.lower()
+ return name
+
def block_size(self):
size = 0
- for type in self.in_types:
- size += type.size
+ for channel in self.channels:
+ size += channel.size
return size
+ def nr_channels(self):
+ nr_channels = 0
+ for channel in self.channels:
+ if channel.size:
+ nr_channels += 1
+ return nr_channels
+
+ def is_array(self):
+ ref_channel = self.channels[0]
+ for channel in self.channels[1:]:
+ if channel.size and (channel.size != ref_channel.size or channel.size % 8):
+ return False
+ return True
+
+ def is_mixed(self):
+ ref_channel = self.channels[0]
+ for channel in self.channels[1:]:
+ if channel.type != VOID:
+ if channel.type != ref_channel.type:
+ return True
+ if channel.norm != ref_channel.norm:
+ return True
+ return False
+
+ def is_pot(self):
+ return is_pot(self.block_size())
+
+ def is_int(self):
+ for channel in self.channels:
+ if channel.type not in (VOID, UNSIGNED, SIGNED):
+ return False
+ return True
+
+ def is_float(self):
+ for channel in self.channels:
+ if channel.type not in (VOID, FLOAT):
+ 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
-_kind_parse_map = {
+_type_parse_map = {
'': VOID,
'x': VOID,
'u': UNSIGNED,
@@ -108,20 +213,55 @@ _swizzle_parse_map = {
def parse(filename):
'''Parse the format descrition in CSV format in terms of the
- Type and Format classes above.'''
+ Channel and Format classes above.'''
stream = open(filename)
formats = []
for line in stream:
- line = line.rstrip()
+ try:
+ comment = line.index('#')
+ except ValueError:
+ pass
+ else:
+ line = line[:comment]
+ 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])
- in_types = []
- for field in fields[4:8]:
+
+ 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 i in range(0, 4):
+ field = fields[4 + i]
if field:
- kind = _kind_parse_map[field[0]]
+ type = _type_parse_map[field[0]]
if field[1] == 'n':
norm = True
size = int(field[2:])
@@ -129,13 +269,13 @@ def parse(filename):
norm = False
size = int(field[1:])
else:
- kind = VOID
+ type = 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))
+ channel = Channel(type, norm, size, names[i])
+ channels.append(channel)
+
+ 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 571cab55dc..4e29d15f3b 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -51,7 +51,7 @@ colorspace_channels_map = {
}
-kind_map = {
+type_map = {
VOID: "UTIL_FORMAT_TYPE_VOID",
UNSIGNED: "UTIL_FORMAT_TYPE_UNSIGNED",
SIGNED: "UTIL_FORMAT_TYPE_SIGNED",
@@ -87,35 +87,44 @@ def write_format_table(formats):
print '#include "u_format.h"'
print
print 'const struct util_format_description'
- print 'util_format_description_table[] = '
- print "{"
- print " {"
- print " PIPE_FORMAT_NONE,"
- print " \"PIPE_FORMAT_NONE\","
- print " {0, 0, 0},"
- print " 0,"
- print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
- print " {0, 0, 0, 0},"
- print " 0"
- print " },"
+ print 'util_format_none_description = {'
+ print " PIPE_FORMAT_NONE,"
+ print " \"PIPE_FORMAT_NONE\","
+ print " {0, 0, 0},"
+ print " 0,"
+ print " 0,"
+ print " 0,"
+ print " 0,"
+ print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
+ print " {0, 0, 0, 0},"
+ print " 0"
+ print "};"
+ print
for format in formats:
+ print 'const struct util_format_description'
+ print 'util_format_%s_description = {' % (format.short_name(),)
+ print " %s," % (format.name,)
+ print " \"%s\"," % (format.name,)
+ print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
+ print " %s," % (layout_map(format.layout),)
+ print " %u,\t/* nr_channels */" % (format.nr_channels(),)
+ print " %s,\t/* is_array */" % (bool_map(format.is_array()),)
+ print " %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)
print " {"
- print " %s," % (format.name,)
- print " \"%s\"," % (format.name,)
- print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
- print " %s," % (layout_map(format.layout),)
- print " {"
for i in range(4):
- type = format.in_types[i]
+ channel = format.channels[i]
if i < 3:
sep = ","
else:
sep = ""
- print " {%s, %s, %u}%s\t/* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
- print " },"
- print " {"
+ 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):
- swizzle = format.out_swizzle[i]
+ swizzle = format.swizzles[i]
if i < 3:
sep = ","
else:
@@ -124,11 +133,30 @@ def write_format_table(formats):
comment = colorspace_channels_map[format.colorspace][i]
except (KeyError, IndexError):
comment = 'ignored'
- print " %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)
- print " },"
- print " %s," % (colorspace_map(format.colorspace),)
+ print " %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)
print " },"
- print "};"
+ print " %s," % (colorspace_map(format.colorspace),)
+ print "};"
+ print
+ print "const struct util_format_description *"
+ print "util_format_description(enum pipe_format format)"
+ print "{"
+ print " if (format >= PIPE_FORMAT_COUNT) {"
+ print " return NULL;"
+ print " }"
+ print
+ print " switch (format) {"
+ print " case PIPE_FORMAT_NONE:"
+ print " return &util_format_none_description;"
+ for format in formats:
+ print " case %s:" % format.name
+ print " return &util_format_%s_description;" % (format.short_name(),)
+ print " default:"
+ print " assert(0);"
+ print " return NULL;"
+ print " }"
+ print "}"
+ print
def main():
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index e95d58ea86..0cb3432c6e 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -90,7 +90,10 @@ pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
static INLINE void
pipe_buffer_reference(struct pipe_buffer **ptr, struct pipe_buffer *buf)
{
- struct pipe_buffer *old_buf = *ptr;
+ struct pipe_buffer *old_buf;
+
+ assert(ptr);
+ old_buf = *ptr;
if (pipe_reference(&(*ptr)->reference, &buf->reference))
old_buf->screen->buffer_destroy(old_buf);
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index b2969a210a..d1ec13def3 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -532,6 +532,17 @@ util_bswap32(uint32_t n)
/**
+ * Reverse byte order of a 16 bit word.
+ */
+static INLINE uint16_t
+util_bswap16(uint16_t n)
+{
+ return (n >> 8) |
+ (n << 8);
+}
+
+
+/**
* Clamp X to [MIN, MAX].
* This is a macro to allow float, int, uint, etc. types.
*/