[Mesa-dev] [PATCH v2 1/4] mesa: add header for share bptc decompress functions
Marek Olšák
maraeo at gmail.com
Mon Jun 25 16:46:26 UTC 2018
This looks OK, but did you try to build other gallium state trackers?
They don't link with anything in src/mesa, so the build will fail,
because the bptc functions are missing. The solution used for other
formats was to put all functions into header files, see
texcompress_*_tmp.h. Another solution would be to move the functions
to src/util, which is shared by all Mesa components.
Also, all the function names (like compress_rgb_float) are too
generic. All non-static non-inline function names are global and
shouldn't conflict with anything else in Mesa, so they need to be more
unique. It's generally a good idea to make public inline function
names look unique to minimize name conflicts.
Marek
On Sat, Jun 23, 2018 at 9:19 AM, Denis Pauk <pauk.denis at gmail.com> wrote:
> Make functions public:
> * fetch_rgba_unorm_from_block
> * fetch_rgb_float_from_block
> * compress_rgba_unorm
> * compress_rgb_float
>
> Create decompress functions:
> * decompress_rgba_unorm
> * decompress_rgb_float
>
> Functions will be reused in gallium/auxiliary code.
>
> v2: Add block decompress function
>
> Signed-off-by: Denis Pauk <pauk.denis at gmail.com>
> CC: Marek Olšák <maraeo at gmail.com>
> ---
> src/mesa/Makefile.sources | 1 +
> src/mesa/main/texcompress_bptc.c | 303 ++++++++++++++++++++++++-
> src/mesa/main/texcompress_bptc_share.h | 58 +++++
> 3 files changed, 358 insertions(+), 4 deletions(-)
> create mode 100644 src/mesa/main/texcompress_bptc_share.h
>
> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
> index 00aba0a2f7..d644112e6a 100644
> --- a/src/mesa/Makefile.sources
> +++ b/src/mesa/Makefile.sources
> @@ -216,6 +216,7 @@ MAIN_FILES = \
> main/texcompress.c \
> main/texcompress_bptc.c \
> main/texcompress_bptc.h \
> + main/texcompress_bptc_share.h \
> main/texcompress_cpal.c \
> main/texcompress_cpal.h \
> main/texcompress_etc.c \
> diff --git a/src/mesa/main/texcompress_bptc.c b/src/mesa/main/texcompress_bptc.c
> index fd37be97f3..74828d63db 100644
> --- a/src/mesa/main/texcompress_bptc.c
> +++ b/src/mesa/main/texcompress_bptc.c
> @@ -29,6 +29,7 @@
> #include <stdbool.h>
> #include "texcompress.h"
> #include "texcompress_bptc.h"
> +#include "texcompress_bptc_share.h"
> #include "util/format_srgb.h"
> #include "util/half_float.h"
> #include "texstore.h"
> @@ -535,7 +536,7 @@ apply_rotation(int rotation,
> result[3] = t;
> }
>
> -static void
> +void
> fetch_rgba_unorm_from_block(const uint8_t *block,
> uint8_t *result,
> int texel)
> @@ -657,6 +658,173 @@ fetch_rgba_unorm_from_block(const uint8_t *block,
> apply_rotation(rotation, result);
> }
>
> +static void
> +decompress_rgba_unorm_block(int src_width, int src_height,
> + const uint8_t *block,
> + uint8_t *dst_row, int dst_rowstride)
> +{
> + int mode_num = ffs(block[0]);
> + const struct bptc_unorm_mode *mode;
> + int bit_offset, secondary_bit_offset;
> + int partition_num;
> + int subset_num;
> + int rotation;
> + int index_selection;
> + int index_bits;
> + int indices[2];
> + int index;
> + int anchors_before_texel;
> + bool anchor;
> + uint8_t endpoints[3 * 2][4];
> + uint32_t subsets;
> + int component;
> + unsigned x, y;
> +
> + if (mode_num == 0) {
> + /* According to the spec this mode is reserved and shouldn't be used. */
> + for(y = 0; y < src_height; y += 1) {
> + uint8_t *result = dst_row;
> + memset(result, 0, 4 * src_width);
> + for(x = 0; x < src_width; x += 1) {
> + result[3] = 0xff;
> + result += 4;
> + }
> + dst_row += dst_rowstride;
> + }
> + return;
> + }
> +
> + mode = bptc_unorm_modes + mode_num - 1;
> + bit_offset = mode_num;
> +
> + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits);
> + bit_offset += mode->n_partition_bits;
> +
> + switch (mode->n_subsets) {
> + case 1:
> + subsets = 0;
> + break;
> + case 2:
> + subsets = partition_table1[partition_num];
> + break;
> + case 3:
> + subsets = partition_table2[partition_num];
> + break;
> + default:
> + assert(false);
> + return;
> + }
> +
> + if (mode->has_rotation_bits) {
> + rotation = extract_bits(block, bit_offset, 2);
> + bit_offset += 2;
> + } else {
> + rotation = 0;
> + }
> +
> + if (mode->has_index_selection_bit) {
> + index_selection = extract_bits(block, bit_offset, 1);
> + bit_offset++;
> + } else {
> + index_selection = 0;
> + }
> +
> + bit_offset = extract_unorm_endpoints(mode, block, bit_offset, endpoints);
> +
> + for(y = 0; y < src_height; y += 1) {
> + uint8_t *result = dst_row;
> + for(x = 0; x < src_width; x += 1) {
> + int texel;
> + texel = x + y * 4;
> +
> + anchors_before_texel = count_anchors_before_texel(mode->n_subsets,
> + partition_num,
> + texel);
> +
> + /* Calculate the offset to the secondary index */
> + secondary_bit_offset = (bit_offset +
> + BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits -
> + mode->n_subsets +
> + mode->n_secondary_index_bits * texel -
> + anchors_before_texel);
> +
> + /* Calculate the offset to the primary index for this texel */
> + bit_offset += mode->n_index_bits * texel - anchors_before_texel;
> +
> + subset_num = (subsets >> (texel * 2)) & 3;
> +
> + anchor = is_anchor(mode->n_subsets, partition_num, texel);
> +
> + index_bits = mode->n_index_bits;
> + if (anchor)
> + index_bits--;
> + indices[0] = extract_bits(block, bit_offset, index_bits);
> +
> + if (mode->n_secondary_index_bits) {
> + index_bits = mode->n_secondary_index_bits;
> + if (anchor)
> + index_bits--;
> + indices[1] = extract_bits(block, secondary_bit_offset, index_bits);
> + }
> +
> + index = indices[index_selection];
> + index_bits = (index_selection ?
> + mode->n_secondary_index_bits :
> + mode->n_index_bits);
> +
> + for (component = 0; component < 3; component++)
> + result[component] = interpolate(endpoints[subset_num * 2][component],
> + endpoints[subset_num * 2 + 1][component],
> + index,
> + index_bits);
> +
> + /* Alpha uses the opposite index from the color components */
> + if (mode->n_secondary_index_bits && !index_selection) {
> + index = indices[1];
> + index_bits = mode->n_secondary_index_bits;
> + } else {
> + index = indices[0];
> + index_bits = mode->n_index_bits;
> + }
> +
> + result[3] = interpolate(endpoints[subset_num * 2][3],
> + endpoints[subset_num * 2 + 1][3],
> + index,
> + index_bits);
> +
> + apply_rotation(rotation, result);
> + result += 4;
> + }
> + dst_row += dst_rowstride;
> + }
> +}
> +
> +void
> +decompress_rgba_unorm(int width, int height,
> + const uint8_t *src, int src_rowstride,
> + uint8_t *dst, int dst_rowstride)
> +{
> + int src_row_diff;
> + int y, x;
> +
> + if (src_rowstride >= width * 4)
> + src_row_diff = src_rowstride - ((width + 3) & ~3) * 4;
> + else
> + src_row_diff = 0;
> +
> + for (y = 0; y < height; y += BLOCK_SIZE) {
> + for (x = 0; x < width; x += BLOCK_SIZE) {
> + decompress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE),
> + MIN2(height - y, BLOCK_SIZE),
> + src,
> + dst + x * 4 + y * dst_rowstride,
> + dst_rowstride);
> + src += BLOCK_BYTES;
> + }
> + src += src_row_diff;
> + }
> +}
> +
> static void
> fetch_bptc_rgba_unorm_bytes(const GLubyte *map,
> GLint rowStride, GLint i, GLint j,
> @@ -840,7 +1008,7 @@ finish_signed_unquantize(int32_t value)
> return value * 31 / 32;
> }
>
> -static void
> +void
> fetch_rgb_float_from_block(const uint8_t *block,
> float *result,
> int texel,
> @@ -921,6 +1089,133 @@ fetch_rgb_float_from_block(const uint8_t *block,
> result[3] = 1.0f;
> }
>
> +static void
> +decompress_rgb_float_block(unsigned src_width, unsigned src_height,
> + const uint8_t *block,
> + float *dst_row, unsigned dst_rowstride,
> + bool is_signed)
> +{
> + int mode_num;
> + const struct bptc_float_mode *mode;
> + int bit_offset;
> + int partition_num;
> + int subset_num;
> + int index_bits;
> + int index;
> + int anchors_before_texel;
> + int32_t endpoints[2 * 2][3];
> + uint32_t subsets;
> + int n_subsets;
> + int component;
> + int32_t value;
> + unsigned x, y;
> +
> + if (block[0] & 0x2) {
> + mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2;
> + bit_offset = 5;
> + } else {
> + mode_num = block[0] & 3;
> + bit_offset = 2;
> + }
> +
> + mode = bptc_float_modes + mode_num;
> +
> + if (mode->reserved) {
> + for(y = 0; y < src_height; y += 1) {
> + float *result = dst_row;
> + memset(result, 0, sizeof result[0] * 4 * src_width);
> + for(x = 0; x < src_width; x += 1) {
> + result[3] = 1.0f;
> + result += 4;
> + }
> + dst_row += dst_rowstride / sizeof dst_row[0];
> + }
> + return;
> + }
> +
> + bit_offset = extract_float_endpoints(mode, block, bit_offset,
> + endpoints, is_signed);
> +
> + if (mode->n_partition_bits) {
> + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits);
> + bit_offset += mode->n_partition_bits;
> +
> + subsets = partition_table1[partition_num];
> + n_subsets = 2;
> + } else {
> + partition_num = 0;
> + subsets = 0;
> + n_subsets = 1;
> + }
> +
> + for(y = 0; y < src_height; y += 1) {
> + float *result = dst_row;
> + for(x = 0; x < src_width; x += 1) {
> + int texel;
> +
> + texel = x + y * 4;
> +
> + anchors_before_texel =
> + count_anchors_before_texel(n_subsets, partition_num, texel);
> +
> + /* Calculate the offset to the primary index for this texel */
> + bit_offset += mode->n_index_bits * texel - anchors_before_texel;
> +
> + subset_num = (subsets >> (texel * 2)) & 3;
> +
> + index_bits = mode->n_index_bits;
> + if (is_anchor(n_subsets, partition_num, texel))
> + index_bits--;
> + index = extract_bits(block, bit_offset, index_bits);
> +
> + for (component = 0; component < 3; component++) {
> + value = interpolate(endpoints[subset_num * 2][component],
> + endpoints[subset_num * 2 + 1][component],
> + index,
> + mode->n_index_bits);
> +
> + if (is_signed)
> + value = finish_signed_unquantize(value);
> + else
> + value = finish_unsigned_unquantize(value);
> +
> + result[component] = _mesa_half_to_float(value);
> + }
> +
> + result[3] = 1.0f;
> + result += 4;
> + }
> + dst_row += dst_rowstride / sizeof dst_row[0];
> + }
> +}
> +
> +void
> +decompress_rgb_float(int width, int height,
> + const uint8_t *src, int src_rowstride,
> + float *dst, int dst_rowstride, bool is_signed)
> +{
> + int src_row_diff;
> + int y, x;
> +
> + if (src_rowstride >= width * 4)
> + src_row_diff = src_rowstride - ((width + 3) & ~3) * 4;
> + else
> + src_row_diff = 0;
> +
> + for (y = 0; y < height; y += BLOCK_SIZE) {
> + for (x = 0; x < width; x += BLOCK_SIZE) {
> + decompress_rgb_float_block(MIN2(width - x, BLOCK_SIZE),
> + MIN2(height - y, BLOCK_SIZE),
> + src,
> + (dst + x * 4 +
> + (y * dst_rowstride / sizeof dst[0])),
> + dst_rowstride, is_signed);
> + src += BLOCK_BYTES;
> + }
> + src += src_row_diff;
> + }
> +}
> +
> static void
> fetch_bptc_rgb_float(const GLubyte *map,
> GLint rowStride, GLint i, GLint j,
> @@ -1247,7 +1542,7 @@ compress_rgba_unorm_block(int src_width, int src_height,
> endpoints);
> }
>
> -static void
> +void
> compress_rgba_unorm(int width, int height,
> const uint8_t *src, int src_rowstride,
> uint8_t *dst, int dst_rowstride)
> @@ -1555,7 +1850,7 @@ compress_rgb_float_block(int src_width, int src_height,
> endpoints);
> }
>
> -static void
> +void
> compress_rgb_float(int width, int height,
> const float *src, int src_rowstride,
> uint8_t *dst, int dst_rowstride,
> diff --git a/src/mesa/main/texcompress_bptc_share.h b/src/mesa/main/texcompress_bptc_share.h
> new file mode 100644
> index 0000000000..b62e58806f
> --- /dev/null
> +++ b/src/mesa/main/texcompress_bptc_share.h
> @@ -0,0 +1,58 @@
> +/*
> + * Copyright (C) 2014 Intel Corporation
> + *
> + * 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 TEXCOMPRESS_BPTC_SHARE_H
> +#define TEXCOMPRESS_BPTC_SHARE_H
> +
> +void
> +fetch_rgba_unorm_from_block(const uint8_t *block,
> + uint8_t *result,
> + int texel);
> +void
> +fetch_rgb_float_from_block(const uint8_t *block,
> + float *result,
> + int texel,
> + bool is_signed);
> +
> +void
> +compress_rgb_float(int width, int height,
> + const float *src, int src_rowstride,
> + uint8_t *dst, int dst_rowstride,
> + bool is_signed);
> +
> +void
> +compress_rgba_unorm(int width, int height,
> + const uint8_t *src, int src_rowstride,
> + uint8_t *dst, int dst_rowstride);
> +
> +void
> +decompress_rgba_unorm(int width, int height,
> + const uint8_t *src, int src_rowstride,
> + uint8_t *dst, int dst_rowstride);
> +
> +void
> +decompress_rgb_float(int width, int height,
> + const uint8_t *src, int src_rowstride,
> + float *dst, int dst_rowstride, bool is_signed);
> +
> +#endif
> --
> 2.17.1
>
More information about the mesa-dev
mailing list