[Mesa-dev] [PATCH v2 1/4] mesa: add header for share bptc decompress functions
Denis Pauk
pauk.denis at gmail.com
Sat Jun 23 13:19:25 UTC 2018
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