From: Dave Airlie <airl...@redhat.com> Like the RGTC code sharing this could be done nicer in the util lib.
This slighty increase i965_dri.so size by ~100 bytes, but it decreases the combined gallium driver by over 1k, and its just nicer to avoid TAG(). Signed-off-by: Dave Airlie <airl...@redhat.com> --- src/gallium/auxiliary/util/u_format_etc.c | 22 ++-- src/mesa/Makefile.sources | 1 - src/mesa/main/texcompress_etc.c | 32 +++--- src/mesa/main/texcompress_etc_tmp.h | 170 ------------------------------ src/util/Makefile.sources | 2 + src/util/format_etc.c | 136 ++++++++++++++++++++++++ src/util/format_etc.h | 78 ++++++++++++++ 7 files changed, 237 insertions(+), 204 deletions(-) delete mode 100644 src/mesa/main/texcompress_etc_tmp.h create mode 100644 src/util/format_etc.c create mode 100644 src/util/format_etc.h diff --git a/src/gallium/auxiliary/util/u_format_etc.c b/src/gallium/auxiliary/util/u_format_etc.c index f909b16..d3c1501 100644 --- a/src/gallium/auxiliary/util/u_format_etc.c +++ b/src/gallium/auxiliary/util/u_format_etc.c @@ -2,18 +2,12 @@ #include "util/u_debug.h" #include "util/u_math.h" #include "u_format_etc.h" - -/* define etc1_parse_block and etc. */ -#define UINT8_TYPE uint8_t -#define TAG(x) x -#include "../../../mesa/main/texcompress_etc_tmp.h" -#undef TAG -#undef UINT8_TYPE +#include "util/format_etc.h" void util_format_etc1_rgb8_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - etc1_unpack_rgba8888(dst_row, dst_stride, src_row, src_stride, width, height); + util_format_etc1_unpack_rgba8888(dst_row, dst_stride, src_row, src_stride, width, height); } void @@ -26,21 +20,21 @@ void util_format_etc1_rgb8_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { const unsigned bw = 4, bh = 4, bs = 8, comps = 4; - struct etc1_block block; + struct util_format_etc1_block block; unsigned x, y, i, j; for (y = 0; y < height; y += bh) { const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { - etc1_parse_block(&block, src); + util_format_etc1_parse_block(&block, src); for (j = 0; j < bh; j++) { float *dst = dst_row + (y + j) * dst_stride / sizeof(*dst_row) + x * comps; uint8_t tmp[3]; for (i = 0; i < bw; i++) { - etc1_fetch_texel(&block, i, j, tmp); + util_format_etc1_fetch_texel(&block, i, j, tmp); dst[0] = ubyte_to_float(tmp[0]); dst[1] = ubyte_to_float(tmp[1]); dst[2] = ubyte_to_float(tmp[2]); @@ -66,13 +60,13 @@ void util_format_etc1_rgb8_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) { const unsigned bw = 4, bh = 4; - struct etc1_block block; + struct util_format_etc1_block block; uint8_t tmp[3]; assert(i < bw && j < bh); - etc1_parse_block(&block, src); - etc1_fetch_texel(&block, i, j, tmp); + util_format_etc1_parse_block(&block, src); + util_format_etc1_fetch_texel(&block, i, j, tmp); dst[0] = ubyte_to_float(tmp[0]); dst[1] = ubyte_to_float(tmp[1]); diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources index b5912b7..9189462 100644 --- a/src/mesa/Makefile.sources +++ b/src/mesa/Makefile.sources @@ -189,7 +189,6 @@ MAIN_FILES = \ main/texcompress_cpal.h \ main/texcompress_etc.c \ main/texcompress_etc.h \ - main/texcompress_etc_tmp.h \ main/texcompress_fxt1.c \ main/texcompress_fxt1.h \ main/texcompress.h \ diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c index 98b4fe2..11daa54 100644 --- a/src/mesa/main/texcompress_etc.c +++ b/src/mesa/main/texcompress_etc.c @@ -44,6 +44,7 @@ #include "macros.h" #include "format_unpack.h" #include "util/format_srgb.h" +#include "util/format_etc.h" struct etc2_block { @@ -97,13 +98,6 @@ static const int etc2_modifier_tables_non_opaque[8][4] = { { 0, 183, 0, -183} }; -/* define etc1_parse_block and etc. */ -#define UINT8_TYPE GLubyte -#define TAG(x) x -#include "texcompress_etc_tmp.h" -#undef TAG -#undef UINT8_TYPE - GLboolean _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS) { @@ -141,9 +135,9 @@ _mesa_etc1_unpack_rgba8888(uint8_t *dst_row, unsigned src_width, unsigned src_height) { - etc1_unpack_rgba8888(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); + util_format_etc1_unpack_rgba8888(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); } static uint8_t @@ -365,8 +359,8 @@ etc2_rgb8_parse_block(struct etc2_block *block, /* Texture decode algorithm is same for individual mode in etc1 * & etc2. */ - block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]); - block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]); + block->base_colors[0][i] = util_format_etc1_base_color_ind_hi(src[i]); + block->base_colors[1][i] = util_format_etc1_base_color_ind_lo(src[i]); } } else if (R_plus_dR < 0 || R_plus_dR > 31){ @@ -446,8 +440,8 @@ etc2_rgb8_parse_block(struct etc2_block *block, /* Texture decode algorithm is same for differential mode in etc1 * & etc2. */ - block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]); - block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]); + block->base_colors[0][i] = util_format_etc1_base_color_diff_hi(src[i]); + block->base_colors[1][i] = util_format_etc1_base_color_diff_lo(src[i]); } } @@ -459,10 +453,10 @@ etc2_rgb8_parse_block(struct etc2_block *block, * or if non punchthrough texture format */ block->modifier_tables[0] = (block->opaque || !punchthrough_alpha) ? - etc1_modifier_tables[table1_idx] : + util_format_etc1_modifier_tables[table1_idx] : etc2_modifier_tables_non_opaque[table1_idx]; block->modifier_tables[1] = (block->opaque || !punchthrough_alpha) ? - etc1_modifier_tables[table2_idx] : + util_format_etc1_modifier_tables[table2_idx] : etc2_modifier_tables_non_opaque[table2_idx]; block->flipped = (src[3] & 0x1); @@ -1256,14 +1250,14 @@ fetch_etc1_rgb8(const GLubyte *map, GLint rowStride, GLint i, GLint j, GLfloat *texel) { - struct etc1_block block; + struct util_format_etc1_block block; GLubyte dst[3]; const GLubyte *src; src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; - etc1_parse_block(&block, src); - etc1_fetch_texel(&block, i % 4, j % 4, dst); + util_format_etc1_parse_block(&block, src); + util_format_etc1_fetch_texel(&block, i % 4, j % 4, dst); texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); diff --git a/src/mesa/main/texcompress_etc_tmp.h b/src/mesa/main/texcompress_etc_tmp.h deleted file mode 100644 index 5497566..0000000 --- a/src/mesa/main/texcompress_etc_tmp.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2011 LunarG, Inc. - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - */ - -/* - * Included by texcompress_etc1 and gallium to define ETC1 decoding routines. - */ - -struct TAG(etc1_block) { - uint32_t pixel_indices; - int flipped; - const int *modifier_tables[2]; - UINT8_TYPE base_colors[2][3]; -}; - -static UINT8_TYPE -TAG(etc1_base_color_diff_hi)(UINT8_TYPE in) -{ - return (in & 0xf8) | (in >> 5); -} - -static UINT8_TYPE -TAG(etc1_base_color_diff_lo)(UINT8_TYPE in) -{ - static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 }; - - in = (in >> 3) + lookup[in & 0x7]; - - return (in << 3) | (in >> 2); -} - -static UINT8_TYPE -TAG(etc1_base_color_ind_hi)(UINT8_TYPE in) -{ - return (in & 0xf0) | ((in & 0xf0) >> 4); -} - -static UINT8_TYPE -TAG(etc1_base_color_ind_lo)(UINT8_TYPE in) -{ - return ((in & 0xf) << 4) | (in & 0xf); -} - -static UINT8_TYPE -TAG(etc1_clamp)(UINT8_TYPE base, int modifier) -{ - int tmp = (int) base + modifier; - - /* CLAMP(tmp, 0, 255) */ - return (UINT8_TYPE) ((tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp)); -} - -static const int TAG(etc1_modifier_tables)[8][4] = { - { 2, 8, -2, -8}, - { 5, 17, -5, -17}, - { 9, 29, -9, -29}, - { 13, 42, -13, -42}, - { 18, 60, -18, -60}, - { 24, 80, -24, -80}, - { 33, 106, -33, -106}, - { 47, 183, -47, -183} -}; - -static void -TAG(etc1_parse_block)(struct TAG(etc1_block) *block, const UINT8_TYPE *src) -{ - if (src[3] & 0x2) { - /* differential mode */ - block->base_colors[0][0] = (int) TAG(etc1_base_color_diff_hi)(src[0]); - block->base_colors[1][0] = (int) TAG(etc1_base_color_diff_lo)(src[0]); - block->base_colors[0][1] = (int) TAG(etc1_base_color_diff_hi)(src[1]); - block->base_colors[1][1] = (int) TAG(etc1_base_color_diff_lo)(src[1]); - block->base_colors[0][2] = (int) TAG(etc1_base_color_diff_hi)(src[2]); - block->base_colors[1][2] = (int) TAG(etc1_base_color_diff_lo)(src[2]); - } - else { - /* individual mode */ - block->base_colors[0][0] = (int) TAG(etc1_base_color_ind_hi)(src[0]); - block->base_colors[1][0] = (int) TAG(etc1_base_color_ind_lo)(src[0]); - block->base_colors[0][1] = (int) TAG(etc1_base_color_ind_hi)(src[1]); - block->base_colors[1][1] = (int) TAG(etc1_base_color_ind_lo)(src[1]); - block->base_colors[0][2] = (int) TAG(etc1_base_color_ind_hi)(src[2]); - block->base_colors[1][2] = (int) TAG(etc1_base_color_ind_lo)(src[2]); - } - - /* pick modifier tables */ - block->modifier_tables[0] = TAG(etc1_modifier_tables)[(src[3] >> 5) & 0x7]; - block->modifier_tables[1] = TAG(etc1_modifier_tables)[(src[3] >> 2) & 0x7]; - - block->flipped = (src[3] & 0x1); - - block->pixel_indices = - (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; -} - -static void -TAG(etc1_fetch_texel)(const struct TAG(etc1_block) *block, - int x, int y, UINT8_TYPE *dst) -{ - const UINT8_TYPE *base_color; - int modifier, bit, idx, blk; - - /* get pixel index */ - bit = y + x * 4; - idx = ((block->pixel_indices >> (15 + bit)) & 0x2) | - ((block->pixel_indices >> (bit)) & 0x1); - - /* get subblock */ - blk = (block->flipped) ? (y >= 2) : (x >= 2); - - base_color = block->base_colors[blk]; - modifier = block->modifier_tables[blk][idx]; - - dst[0] = TAG(etc1_clamp)(base_color[0], modifier); - dst[1] = TAG(etc1_clamp)(base_color[1], modifier); - dst[2] = TAG(etc1_clamp)(base_color[2], modifier); -} - -static void -etc1_unpack_rgba8888(uint8_t *dst_row, - unsigned dst_stride, - const uint8_t *src_row, - unsigned src_stride, - unsigned width, - unsigned height) -{ - const unsigned bw = 4, bh = 4, bs = 8, comps = 4; - struct etc1_block block; - unsigned x, y, i, j; - - for (y = 0; y < height; y += bh) { - const uint8_t *src = src_row; - - for (x = 0; x < width; x+= bw) { - etc1_parse_block(&block, src); - - for (j = 0; j < MIN2(bh, height - y); j++) { - uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < MIN2(bw, width - x); i++) { - etc1_fetch_texel(&block, i, j, dst); - dst[3] = 255; - dst += comps; - } - } - - src += bs; - } - - src_row += src_stride; - } -} diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources index 1e29a03..0375eb8 100644 --- a/src/util/Makefile.sources +++ b/src/util/Makefile.sources @@ -11,6 +11,8 @@ MESA_UTIL_FILES := \ ralloc.h \ register_allocate.c \ register_allocate.h \ + format_etc.c \ + format_etc.h \ rgtc.c \ rgtc.h \ set.c \ diff --git a/src/util/format_etc.c b/src/util/format_etc.c new file mode 100644 index 0000000..5676bbf --- /dev/null +++ b/src/util/format_etc.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2011 LunarG, Inc. + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 "format_etc.h" +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) + +const int util_format_etc_lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 }; + +const int util_format_etc1_modifier_tables[8][4] = { + { 2, 8, -2, -8}, + { 5, 17, -5, -17}, + { 9, 29, -9, -29}, + { 13, 42, -13, -42}, + { 18, 60, -18, -60}, + { 24, 80, -24, -80}, + { 33, 106, -33, -106}, + { 47, 183, -47, -183} +}; + +static uint8_t +util_format_etc1_clamp(uint8_t base, int modifier) +{ + int tmp = (int) base + modifier; + + /* CLAMP(tmp, 0, 255) */ + return (uint8_t) ((tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp)); +} + +void +util_format_etc1_parse_block(struct util_format_etc1_block *block, const uint8_t *src) +{ + if (src[3] & 0x2) { + /* differential mode */ + block->base_colors[0][0] = (int) util_format_etc1_base_color_diff_hi(src[0]); + block->base_colors[1][0] = (int) util_format_etc1_base_color_diff_lo(src[0]); + block->base_colors[0][1] = (int) util_format_etc1_base_color_diff_hi(src[1]); + block->base_colors[1][1] = (int) util_format_etc1_base_color_diff_lo(src[1]); + block->base_colors[0][2] = (int) util_format_etc1_base_color_diff_hi(src[2]); + block->base_colors[1][2] = (int) util_format_etc1_base_color_diff_lo(src[2]); + } + else { + /* individual mode */ + block->base_colors[0][0] = (int) util_format_etc1_base_color_ind_hi(src[0]); + block->base_colors[1][0] = (int) util_format_etc1_base_color_ind_lo(src[0]); + block->base_colors[0][1] = (int) util_format_etc1_base_color_ind_hi(src[1]); + block->base_colors[1][1] = (int) util_format_etc1_base_color_ind_lo(src[1]); + block->base_colors[0][2] = (int) util_format_etc1_base_color_ind_hi(src[2]); + block->base_colors[1][2] = (int) util_format_etc1_base_color_ind_lo(src[2]); + } + + /* pick modifier tables */ + block->modifier_tables[0] = util_format_etc1_modifier_tables[(src[3] >> 5) & 0x7]; + block->modifier_tables[1] = util_format_etc1_modifier_tables[(src[3] >> 2) & 0x7]; + + block->flipped = (src[3] & 0x1); + + block->pixel_indices = + (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; +} + +void +util_format_etc1_fetch_texel(const struct util_format_etc1_block *block, + int x, int y, uint8_t *dst) +{ + const uint8_t *base_color; + int modifier, bit, idx, blk; + + /* get pixel index */ + bit = y + x * 4; + idx = ((block->pixel_indices >> (15 + bit)) & 0x2) | + ((block->pixel_indices >> (bit)) & 0x1); + + /* get subblock */ + blk = (block->flipped) ? (y >= 2) : (x >= 2); + + base_color = block->base_colors[blk]; + modifier = block->modifier_tables[blk][idx]; + + dst[0] = util_format_etc1_clamp(base_color[0], modifier); + dst[1] = util_format_etc1_clamp(base_color[1], modifier); + dst[2] = util_format_etc1_clamp(base_color[2], modifier); +} + +void +util_format_etc1_unpack_rgba8888(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned width, + unsigned height) +{ + const unsigned bw = 4, bh = 4, bs = 8, comps = 4; + struct util_format_etc1_block block; + unsigned x, y, i, j; + + for (y = 0; y < height; y += bh) { + const uint8_t *src = src_row; + + for (x = 0; x < width; x+= bw) { + util_format_etc1_parse_block(&block, src); + + for (j = 0; j < MIN2(bh, height - y); j++) { + uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; + for (i = 0; i < MIN2(bw, width - x); i++) { + util_format_etc1_fetch_texel(&block, i, j, dst); + dst[3] = 255; + dst += comps; + } + } + + src += bs; + } + + src_row += src_stride; + } +} diff --git a/src/util/format_etc.h b/src/util/format_etc.h new file mode 100644 index 0000000..fe74f20 --- /dev/null +++ b/src/util/format_etc.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2014 Red Hat + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _FORMAT_ETC_H +#define _FORMAT_ETC_H + +#include <stdint.h> +#include "c99_compat.h" + +struct util_format_etc1_block { + uint32_t pixel_indices; + int flipped; + const int *modifier_tables[2]; + uint8_t base_colors[2][3]; +}; + +void util_format_etc1_unpack_rgba8888(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned width, + unsigned height); + +void util_format_etc1_parse_block(struct util_format_etc1_block *block, const uint8_t *src); +void util_format_etc1_fetch_texel(const struct util_format_etc1_block *block, + int x, int y, uint8_t *dst); + +extern const int util_format_etc_lookup[8]; + +static inline uint8_t +util_format_etc1_base_color_diff_hi(uint8_t in) +{ + return (in & 0xf8) | (in >> 5); +} + +static inline uint8_t +util_format_etc1_base_color_diff_lo(uint8_t in) +{ + in = (in >> 3) + util_format_etc_lookup[in & 0x7]; + + return (in << 3) | (in >> 2); +} + +static inline uint8_t +util_format_etc1_base_color_ind_hi(uint8_t in) +{ + return (in & 0xf0) | ((in & 0xf0) >> 4); +} + +static inline uint8_t +util_format_etc1_base_color_ind_lo(uint8_t in) +{ + return ((in & 0xf) << 4) | (in & 0xf); +} + +extern const int util_format_etc1_modifier_tables[8][4]; +#endif /* _RGTC_H */ -- 1.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev