From: José Fonseca Date: Wed, 31 Mar 2010 19:15:17 +0000 (+0100) Subject: util: Add callback to fetch a single pixel. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69895725cfe9d4dc917ff6e643af9e6e3a6e093f;p=mesa.git util: Add callback to fetch a single pixel. --- diff --git a/progs/gallium/unit/u_format_test.c b/progs/gallium/unit/u_format_test.c index e96f0a9d12d..ba4e9fab66d 100644 --- a/progs/gallium/unit/u_format_test.c +++ b/progs/gallium/unit/u_format_test.c @@ -33,6 +33,37 @@ #include "util/u_format_tests.h" +static boolean +test_format_fetch_float(const struct util_format_description *format_desc, + const struct util_format_test_case *test) +{ + float unpacked[4]; + unsigned i; + boolean success; + + /* + * TODO: test block formats too. + */ + if (format_desc->block.width != 1 && format_desc->block.height != 1) { + return TRUE; + } + + format_desc->fetch_float(unpacked, test->packed, 0, 0); + + success = TRUE; + for (i = 0; i < 4; ++i) + if (test->unpacked[i] != unpacked[i]) + success = FALSE; + + if (!success) { + printf("FAILED: (%f %f %f %f) obtained\n", unpacked[0], unpacked[1], unpacked[2], unpacked[3]); + printf(" (%f %f %f %f) expected\n", test->unpacked[0], test->unpacked[1], test->unpacked[2], test->unpacked[3]); + } + + return success; +} + + static boolean test_format_unpack_float(const struct util_format_description *format_desc, const struct util_format_test_case *test) @@ -225,6 +256,9 @@ test_all(void) { bool success = TRUE; + if (!test_one(&test_format_fetch_float, "fetch_float")) + success = FALSE; + if (!test_one(&test_format_pack_float, "pack_float")) success = FALSE; diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 609d398ebfc..8e76e13b664 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -191,21 +191,34 @@ struct util_format_description enum util_format_colorspace colorspace; /** - * Accessor functions. + * Unpack a span of pixel blocks to R8G8B8A8_UNORM. */ - void (*unpack_8unorm)(uint8_t *dst, const uint8_t *src, unsigned nr_blocks); + /** + * Pack a span of pixel blocks from R8G8B8A8_UNORM. + */ void (*pack_8unorm)(uint8_t *dst, const uint8_t *src, unsigned nr_blocks); + /** + * Unpack a span of pixel blocks to R32G32B32A32_FLOAT. + */ void (*unpack_float)(float *dst, const uint8_t *src, unsigned nr_blocks); + /** + * Pack a span of pixel blocks from R32G32B32A32_FLOAT. + */ void (*pack_float)(uint8_t *dst, const float *src, unsigned nr_blocks); + /** + * Fetch a single pixel (i, j) from a block. + */ + void + (*fetch_float)(float *dst, const uint8_t *src, unsigned i, unsigned j); }; diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py index 4831912f029..c74900ce63e 100644 --- a/src/gallium/auxiliary/util/u_format_pack.py +++ b/src/gallium/auxiliary/util/u_format_pack.py @@ -324,115 +324,190 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True 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() - - print 'static INLINE void' - print 'util_format_%s_unpack_%s(%s *dst, const uint8_t *src, unsigned length)' % (name, dst_suffix, dst_native_type) - print '{' +def generate_unpack_kernel(format, dst_channel, dst_native_type): - if is_format_supported(format): - - assert format.layout == PLAIN - - src_native_type = native_type(format) - - print ' while(length--) {' - - if format.is_bitmask(): - depth = format.block_size() - print ' uint%u_t value = *(uint%u_t *)src;' % (depth, depth) + if not is_format_supported(format): + return - # Declare the intermediate variables - for i in range(format.nr_channels()): - src_channel = format.channels[i] - if src_channel.type == UNSIGNED: - print ' uint%u_t %s;' % (depth, src_channel.name) - elif src_channel.type == SIGNED: - print ' int%u_t %s;' % (depth, src_channel.name) + assert format.layout == PLAIN + + src_native_type = native_type(format) + + if format.is_bitmask(): + depth = format.block_size() + print ' uint%u_t value = *(uint%u_t *)src;' % (depth, depth) + + # Declare the intermediate variables + for i in range(format.nr_channels()): + src_channel = format.channels[i] + if src_channel.type == UNSIGNED: + print ' uint%u_t %s;' % (depth, src_channel.name) + elif src_channel.type == SIGNED: + print ' int%u_t %s;' % (depth, src_channel.name) + + print ' #ifdef PIPE_ARCH_BIG_ENDIAN' + print ' value = util_bswap%u(value);' % depth + print ' #endif' + + # Compute the intermediate unshifted values + shift = 0 + for i in range(format.nr_channels()): + src_channel = format.channels[i] + value = 'value' + if src_channel.type == UNSIGNED: + if shift: + value = '%s >> %u' % (value, shift) + if shift + src_channel.size < depth: + value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1) + elif src_channel.type == SIGNED: + if shift + src_channel.size < depth: + # Align the sign bit + lshift = depth - (shift + src_channel.size) + value = '%s << %u' % (value, lshift) + # Cast to signed + value = '(int%u_t)(%s) ' % (depth, value) + if src_channel.size < depth: + # Align the LSB bit + rshift = depth - src_channel.size + value = '(%s) >> %u' % (value, rshift) + else: + value = None + + if value is not None: + print ' %s = %s;' % (src_channel.name, value) + + shift += src_channel.size + + # Convert, swizzle, and store final values + for i in range(4): + swizzle = format.swizzles[i] + if swizzle < 4: + src_channel = format.channels[swizzle] + value = 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]) + + else: + print ' union util_format_%s pixel;' % format.short_name() + print ' memcpy(&pixel, src, sizeof pixel);' + bswap_format(format) - print ' #ifdef PIPE_ARCH_BIG_ENDIAN' - print ' value = util_bswap%u(value);' % depth - print ' #endif' + 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]) - # Compute the intermediate unshifted values - shift = 0 - for i in range(format.nr_channels()): - src_channel = format.channels[i] - value = 'value' - if src_channel.type == UNSIGNED: - if shift: - value = '%s >> %u' % (value, shift) - if shift + src_channel.size < depth: - value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1) - elif src_channel.type == SIGNED: - if shift + src_channel.size < depth: - # Align the sign bit - lshift = depth - (shift + src_channel.size) - value = '%s << %u' % (value, lshift) - # Cast to signed - value = '(int%u_t)(%s) ' % (depth, value) - if src_channel.size < depth: - # Align the LSB bit - rshift = depth - src_channel.size - value = '(%s) >> %u' % (value, rshift) - else: - value = None - - if value is not None: - print ' %s = %s;' % (src_channel.name, value) - - shift += src_channel.size + +def generate_pack_kernel(format, src_channel, src_native_type): + + if not is_format_supported(format): + return - # Convert, swizzle, and store final values - for i in range(4): - swizzle = format.swizzles[i] - if swizzle < 4: - src_channel = format.channels[swizzle] - value = 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 + dst_native_type = native_type(format) + + assert format.layout == PLAIN + + inv_swizzle = format.inv_swizzles() + + if format.is_bitmask(): + depth = format.block_size() + print ' uint%u_t value = 0;' % depth + + shift = 0 + for i in range(4): + dst_channel = format.channels[i] + if inv_swizzle[i] is not None: + value ='src[%u]' % 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 = 'dst[0]' - print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i]) - - else: - print ' union util_format_%s pixel;' % format.short_name() - print ' memcpy(&pixel, src, sizeof pixel);' - bswap_format(format) + value = '0' + if dst_channel.type in (UNSIGNED, SIGNED): + if shift + dst_channel.size < depth: + value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1) + if shift: + value = '(%s) << %u' % (value, shift) + if dst_channel.type == SIGNED: + # Cast to unsigned + value = '(uint%u_t)(%s) ' % (depth, value) + else: + value = None + if value is not None: + print ' value |= %s;' % (value) + + shift += dst_channel.size + + print '#ifdef PIPE_ARCH_BIG_ENDIAN' + print ' value = util_bswap%u(value);' % depth + print '#endif' - 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: + print ' *(uint%u_t *)dst = value;' % depth + + else: + print ' union util_format_%s pixel;' % format.short_name() + + for i in range(4): + dst_channel = format.channels[i] + width = dst_channel.size + if inv_swizzle[i] is None: + continue + value ='src[%u]' % 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 swizzle == SWIZZLE_NONE: + elif i >= 1: 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 ' pixel.chan.%s = %s;' % (dst_channel.name, value) + + bswap_format(format) + print ' memcpy(dst, &pixel, sizeof pixel);' + + +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() + + print 'static INLINE void' + print 'util_format_%s_unpack_%s(%s *dst, const uint8_t *src, unsigned length)' % (name, dst_suffix, dst_native_type) + print '{' + + if is_format_supported(format): + print ' while(length--) {' + + generate_unpack_kernel(format, dst_channel, dst_native_type) print ' src += %u;' % (format.block_size() / 8,) print ' dst += 4;' @@ -452,69 +527,9 @@ def generate_format_pack(format, src_channel, src_native_type, src_suffix): print '{' if is_format_supported(format): - dst_native_type = native_type(format) - - assert format.layout == PLAIN - - inv_swizzle = format.inv_swizzles() - print ' while(length--) {' - if format.is_bitmask(): - depth = format.block_size() - print ' uint%u_t value = 0;' % depth - - shift = 0 - for i in range(4): - dst_channel = format.channels[i] - if inv_swizzle[i] is not None: - value ='src[%u]' % 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' - if dst_channel.type in (UNSIGNED, SIGNED): - if shift + dst_channel.size < depth: - value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1) - if shift: - value = '(%s) << %u' % (value, shift) - if dst_channel.type == SIGNED: - # Cast to unsigned - value = '(uint%u_t)(%s) ' % (depth, value) - else: - value = None - if value is not None: - print ' value |= %s;' % (value) - - shift += dst_channel.size - - print '#ifdef PIPE_ARCH_BIG_ENDIAN' - print ' value = util_bswap%u(value);' % depth - print '#endif' - - print ' *(uint%u_t *)dst = value;' % depth - - else: - print ' union util_format_%s pixel;' % format.short_name() - - for i in range(4): - dst_channel = format.channels[i] - width = dst_channel.size - if inv_swizzle[i] is None: - continue - value ='src[%u]' % 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);' + generate_pack_kernel(format, src_channel, src_native_type) print ' src += 4;' print ' dst += %u;' % (format.block_size() / 8,) @@ -524,18 +539,20 @@ def generate_format_pack(format, src_channel, src_native_type, src_suffix): print -def generate_unpack(formats, dst_channel, dst_native_type, dst_suffix): - '''Generate the dispatch function to unpack pixels from any format''' +def generate_format_fetch(format, dst_channel, dst_native_type, dst_suffix): + '''Generate the function to unpack pixels from a particular format''' - for format in formats: - generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix) + name = format.short_name() + print 'static INLINE void' + print 'util_format_%s_fetch_%s(%s *dst, const uint8_t *src, unsigned i, unsigned j)' % (name, dst_suffix, dst_native_type) + print '{' -def generate_pack(formats, src_channel, src_native_type, src_suffix): - '''Generate the dispatch function to pack pixels to any format''' + if is_format_supported(format): + generate_unpack_kernel(format, dst_channel, dst_native_type) - for format in formats: - generate_format_pack(format, src_channel, src_native_type, src_suffix) + print '}' + print def generate(formats): @@ -555,13 +572,16 @@ def generate(formats): native_type = 'float' suffix = 'float' - generate_unpack(formats, channel, native_type, suffix) - generate_pack(formats, channel, native_type, suffix) + for format in formats: + generate_format_unpack(format, channel, native_type, suffix) + generate_format_pack(format, channel, native_type, suffix) + generate_format_fetch(format, channel, native_type, suffix) channel = Channel(UNSIGNED, True, 8) native_type = 'uint8_t' suffix = '8unorm' - generate_unpack(formats, channel, native_type, suffix) - generate_pack(formats, channel, native_type, suffix) + for format in formats: + generate_format_unpack(format, channel, native_type, suffix) + generate_format_pack(format, channel, native_type, suffix) diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py index fe910d9a772..6877bd6844c 100755 --- a/src/gallium/auxiliary/util/u_format_table.py +++ b/src/gallium/auxiliary/util/u_format_table.py @@ -106,6 +106,11 @@ util_format_none_unpack_float(float *dst, const uint8_t *src, unsigned length) static void util_format_none_pack_float(uint8_t *dst, const float *src, unsigned length) { +} + +static void +util_format_none_fetch_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ } ''' print 'const struct util_format_description' @@ -125,7 +130,8 @@ util_format_none_pack_float(uint8_t *dst, const float *src, unsigned length) print " &util_format_none_unpack_8unorm," print " &util_format_none_pack_8unorm," print " &util_format_none_unpack_float," - print " &util_format_none_pack_float" + print " &util_format_none_pack_float," + print " &util_format_none_fetch_float" print "};" print @@ -172,7 +178,8 @@ util_format_none_pack_float(uint8_t *dst, const float *src, unsigned length) print " &util_format_%s_unpack_8unorm," % format.short_name() print " &util_format_%s_pack_8unorm," % format.short_name() print " &util_format_%s_unpack_float," % format.short_name() - print " &util_format_%s_pack_float" % format.short_name() + print " &util_format_%s_pack_float," % format.short_name() + print " &util_format_%s_fetch_float" % format.short_name() print "};" print