From ad51f5bd13cfc29f7d9d7de35c343b5f94e79ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tapani=20P=C3=A4lli?= Date: Tue, 10 Jan 2023 12:41:27 +0200 Subject: [PATCH] mesa/st: add astc decoder lookup tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit introduces ASTC decoding lookup tables from Granite 3D engine. These lookup tables will be used during transcoding by a compute shader in later commits when decoding ASTC textures. Signed-off-by: Tapani Pälli Reviewed-by: Nanley Chery Part-of: --- src/mesa/main/texcompress_astc_luts.cpp | 532 +++++++++++++++++++ src/mesa/main/texcompress_astc_luts.h | 127 +++++ src/mesa/main/texcompress_astc_luts_wrap.cpp | 65 +++ src/mesa/main/texcompress_astc_luts_wrap.h | 62 +++ src/mesa/meson.build | 4 + 5 files changed, 790 insertions(+) create mode 100644 src/mesa/main/texcompress_astc_luts.cpp create mode 100644 src/mesa/main/texcompress_astc_luts.h create mode 100644 src/mesa/main/texcompress_astc_luts_wrap.cpp create mode 100644 src/mesa/main/texcompress_astc_luts_wrap.h diff --git a/src/mesa/main/texcompress_astc_luts.cpp b/src/mesa/main/texcompress_astc_luts.cpp new file mode 100644 index 00000000000..6ffaf23ea88 --- /dev/null +++ b/src/mesa/main/texcompress_astc_luts.cpp @@ -0,0 +1,532 @@ +/* Copyright (c) 2017-2022 Hans-Kristian Arntzen + * + * 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 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 +#include +#include +#include +#include +#include + +#include "texcompress_astc_luts.h" + +namespace Granite +{ +static void build_astc_unquant_weight_lut(uint8_t *lut, size_t range, const ASTCQuantizationMode &mode) +{ + for (size_t i = 0; i < range; i++) + { + auto &v = lut[i]; + + if (!mode.quints && !mode.trits) + { + switch (mode.bits) + { + case 1: + v = i * 63; + break; + + case 2: + v = i * 0x15; + break; + + case 3: + v = i * 9; + break; + + case 4: + v = (i << 2) | (i >> 2); + break; + + case 5: + v = (i << 1) | (i >> 4); + break; + + default: + v = 0; + break; + } + } + else if (mode.bits == 0) + { + if (mode.trits) + v = 32 * i; + else + v = 16 * i; + } + else + { + unsigned b = (i >> 1) & 1; + unsigned c = (i >> 2) & 1; + unsigned A, B, C, D; + + A = 0x7f * (i & 1); + D = i >> mode.bits; + B = 0; + + if (mode.trits) + { + static const unsigned Cs[3] = { 50, 23, 11 }; + C = Cs[mode.bits - 1]; + if (mode.bits == 2) + B = 0x45 * b; + else if (mode.bits == 3) + B = 0x21 * b + 0x42 * c; + } + else + { + static const unsigned Cs[2] = { 28, 13 }; + C = Cs[mode.bits - 1]; + if (mode.bits == 2) + B = 0x42 * b; + } + + unsigned unq = D * C + B; + unq ^= A; + unq = (A & 0x20) | (unq >> 2); + v = unq; + } + + // Expand [0, 63] to [0, 64]. + if (mode.bits != 0 && v > 32) + v++; + } +} + +static void build_astc_unquant_endpoint_lut(uint8_t *lut, size_t range, const ASTCQuantizationMode &mode) +{ + for (size_t i = 0; i < range; i++) + { + auto &v = lut[i]; + + if (!mode.quints && !mode.trits) + { + // Bit-replication. + switch (mode.bits) + { + case 1: + v = i * 0xff; + break; + + case 2: + v = i * 0x55; + break; + + case 3: + v = (i << 5) | (i << 2) | (i >> 1); + break; + + case 4: + v = i * 0x11; + break; + + case 5: + v = (i << 3) | (i >> 2); + break; + + case 6: + v = (i << 2) | (i >> 4); + break; + + case 7: + v = (i << 1) | (i >> 6); + break; + + default: + v = i; + break; + } + } + else + { + unsigned A, B, C, D; + unsigned b = (i >> 1) & 1; + unsigned c = (i >> 2) & 1; + unsigned d = (i >> 3) & 1; + unsigned e = (i >> 4) & 1; + unsigned f = (i >> 5) & 1; + + B = 0; + D = i >> mode.bits; + A = (i & 1) * 0x1ff; + + if (mode.trits) + { + static const unsigned Cs[6] = { 204, 93, 44, 22, 11, 5 }; + C = Cs[mode.bits - 1]; + + switch (mode.bits) + { + case 2: + B = b * 0x116; + break; + + case 3: + B = b * 0x85 + c * 0x10a; + break; + + case 4: + B = b * 0x41 + c * 0x82 + d * 0x104; + break; + + case 5: + B = b * 0x20 + c * 0x40 + d * 0x81 + e * 0x102; + break; + + case 6: + B = b * 0x10 + c * 0x20 + d * 0x40 + e * 0x80 + f * 0x101; + break; + } + } + else + { + static const unsigned Cs[5] = { 113, 54, 26, 13, 6 }; + C = Cs[mode.bits - 1]; + + switch (mode.bits) + { + case 2: + B = b * 0x10c; + break; + + case 3: + B = b * 0x82 + c * 0x105; + break; + + case 4: + B = b * 0x40 + c * 0x81 + d * 0x102; + break; + + case 5: + B = b * 0x20 + c * 0x40 + d * 0x80 + e * 0x101; + break; + } + } + + unsigned unq = D * C + B; + unq ^= A; + unq = (A & 0x80) | (unq >> 2); + v = uint8_t(unq); + } + } +} + +static unsigned astc_value_range(const ASTCQuantizationMode &mode) +{ + unsigned value_range = 1u << mode.bits; + if (mode.trits) + value_range *= 3; + if (mode.quints) + value_range *= 5; + + if (value_range == 1) + value_range = 0; + return value_range; +} + +static uint32_t astc_hash52(uint32_t p) +{ + p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; + p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3; + p ^= p << 6; p ^= p >> 17; + return p; +} + +// Copy-paste from spec. +static int astc_select_partition(int seed, int x, int y, int z, int partitioncount, bool small_block) +{ + if (small_block) + { + x <<= 1; + y <<= 1; + z <<= 1; + } + + seed += (partitioncount - 1) * 1024; + uint32_t rnum = astc_hash52(seed); + uint8_t seed1 = rnum & 0xF; + uint8_t seed2 = (rnum >> 4) & 0xF; + uint8_t seed3 = (rnum >> 8) & 0xF; + uint8_t seed4 = (rnum >> 12) & 0xF; + uint8_t seed5 = (rnum >> 16) & 0xF; + uint8_t seed6 = (rnum >> 20) & 0xF; + uint8_t seed7 = (rnum >> 24) & 0xF; + uint8_t seed8 = (rnum >> 28) & 0xF; + uint8_t seed9 = (rnum >> 18) & 0xF; + uint8_t seed10 = (rnum >> 22) & 0xF; + uint8_t seed11 = (rnum >> 26) & 0xF; + uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; + + seed1 *= seed1; seed2 *= seed2; seed3 *= seed3; seed4 *= seed4; + seed5 *= seed5; seed6 *= seed6; seed7 *= seed7; seed8 *= seed8; + seed9 *= seed9; seed10 *= seed10; seed11 *= seed11; seed12 *= seed12; + + int sh1, sh2, sh3; + if (seed & 1) + { + sh1 = seed & 2 ? 4 : 5; + sh2 = partitioncount == 3 ? 6 : 5; + } + else + { + sh1 = partitioncount == 3 ? 6 : 5; + sh2 = seed & 2 ? 4 : 5; + } + sh3 = (seed & 0x10) ? sh1 : sh2; + + seed1 >>= sh1; seed2 >>= sh2; seed3 >>= sh1; seed4 >>= sh2; + seed5 >>= sh1; seed6 >>= sh2; seed7 >>= sh1; seed8 >>= sh2; + seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3; + + int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14); + int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10); + int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6); + int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2); + + a &= 0x3f; b &= 0x3f; c &= 0x3f; d &= 0x3f; + + if (partitioncount < 4) + d = 0; + if (partitioncount < 3) + c = 0; + + if (a >= b && a >= c && a >= d) + return 0; + else if (b >= c && b >= d) + return 1; + else if (c >= d) + return 2; + else + return 3; +} + +ASTCLutHolder::PartitionTable::PartitionTable(unsigned block_width, unsigned block_height) +{ + bool small_block = (block_width * block_height) < 31; + + lut_width = block_width * 32; + lut_height = block_height * 32; + lut_buffer.resize(lut_width * lut_height); + + for (unsigned seed_y = 0; seed_y < 32; seed_y++) + { + for (unsigned seed_x = 0; seed_x < 32; seed_x++) + { + unsigned seed = seed_y * 32 + seed_x; + for (unsigned block_y = 0; block_y < block_height; block_y++) + { + for (unsigned block_x = 0; block_x < block_width; block_x++) + { + int part2 = astc_select_partition(seed, block_x, block_y, 0, 2, small_block); + int part3 = astc_select_partition(seed, block_x, block_y, 0, 3, small_block); + int part4 = astc_select_partition(seed, block_x, block_y, 0, 4, small_block); + lut_buffer[(seed_y * block_height + block_y) * lut_width + (seed_x * block_width + block_x)] = + (part2 << 0) | (part3 << 2) | (part4 << 4); + } + } + } + } +} + +ASTCLutHolder::PartitionTable &ASTCLutHolder::get_partition_table(unsigned width, unsigned height) +{ + std::lock_guard holder{table_lock}; + auto itr = tables.find(width * 16 + height); + if (itr != tables.end()) + { + return itr->second; + } + else + { + auto &t = tables[width * 16 + height]; + t = { width, height }; + return t; + } +} + +ASTCLutHolder &get_astc_luts() +{ + static ASTCLutHolder holder; + return holder; +} + +ASTCLutHolder::ASTCLutHolder() +{ + init_color_endpoint(); + init_weight_luts(); + init_trits_quints(); +} + +void ASTCLutHolder::init_color_endpoint() +{ + auto &unquant_lut = color_endpoint.unquant_lut; + + for (size_t i = 0; i < astc_num_quantization_modes; i++) + { + auto value_range = astc_value_range(astc_quantization_modes[i]); + color_endpoint.unquant_lut_offsets[i] = color_endpoint.unquant_offset; + build_astc_unquant_endpoint_lut(unquant_lut + color_endpoint.unquant_offset, value_range, astc_quantization_modes[i]); + color_endpoint.unquant_offset += value_range; + } + + auto &lut = color_endpoint.lut; + + // We can have a maximum of 9 endpoint pairs, i.e. 18 endpoint values in total. + for (unsigned pairs_minus_1 = 0; pairs_minus_1 < 9; pairs_minus_1++) + { + for (unsigned remaining = 0; remaining < 128; remaining++) + { + bool found_mode = false; + for (auto &mode : astc_quantization_modes) + { + unsigned num_values = (pairs_minus_1 + 1) * 2; + unsigned total_bits = mode.bits * num_values + + (mode.quints * 7 * num_values + 2) / 3 + + (mode.trits * 8 * num_values + 4) / 5; + + if (total_bits <= remaining) + { + found_mode = true; + lut[pairs_minus_1][remaining][0] = mode.bits; + lut[pairs_minus_1][remaining][1] = mode.trits; + lut[pairs_minus_1][remaining][2] = mode.quints; + lut[pairs_minus_1][remaining][3] = color_endpoint.unquant_lut_offsets[&mode - astc_quantization_modes]; + break; + } + } + + if (!found_mode) + memset(lut[pairs_minus_1][remaining], 0, sizeof(lut[pairs_minus_1][remaining])); + } + } +} + +void ASTCLutHolder::init_weight_luts() +{ + auto &lut = weights.lut; + auto &unquant_lut = weights.unquant_lut; + auto &unquant_offset = weights.unquant_offset; + + for (size_t i = 0; i < astc_num_weight_modes; i++) + { + auto value_range = astc_value_range(astc_weight_modes[i]); + lut[i][0] = astc_weight_modes[i].bits; + lut[i][1] = astc_weight_modes[i].trits; + lut[i][2] = astc_weight_modes[i].quints; + lut[i][3] = unquant_offset; + build_astc_unquant_weight_lut(unquant_lut + unquant_offset, value_range, astc_weight_modes[i]); + unquant_offset += value_range; + } + + assert(unquant_offset <= 256); +} + +void ASTCLutHolder::init_trits_quints() +{ + // From specification. + auto &trits_quints = integer.trits_quints; + + for (unsigned T = 0; T < 256; T++) + { + unsigned C; + uint8_t t0, t1, t2, t3, t4; + + if (((T >> 2) & 7) == 7) + { + C = (((T >> 5) & 7) << 2) | (T & 3); + t4 = t3 = 2; + } + else + { + C = T & 0x1f; + if (((T >> 5) & 3) == 3) + { + t4 = 2; + t3 = (T >> 7) & 1; + } + else + { + t4 = (T >> 7) & 1; + t3 = (T >> 5) & 3; + } + } + + if ((C & 3) == 3) + { + t2 = 2; + t1 = (C >> 4) & 1; + t0 = (((C >> 3) & 1) << 1) | (((C >> 2) & 1) & ~(((C >> 3) & 1))); + } + else if (((C >> 2) & 3) == 3) + { + t2 = 2; + t1 = 2; + t0 = C & 3; + } + else + { + t2 = (C >> 4) & 1; + t1 = (C >> 2) & 3; + t0 = (((C >> 1) & 1) << 1) | ((C & 1) & ~(((C >> 1) & 1))); + } + + trits_quints[T] = t0 | (t1 << 3) | (t2 << 6) | (t3 << 9) | (t4 << 12); + } + + for (unsigned Q = 0; Q < 128; Q++) + { + unsigned C; + uint8_t q0, q1, q2; + if (((Q >> 1) & 3) == 3 && ((Q >> 5) & 3) == 0) + { + q2 = ((Q & 1) << 2) | ((((Q >> 4) & 1) & ~(Q & 1)) << 1) | (((Q >> 3) & 1) & ~(Q & 1)); + q1 = q0 = 4; + } + else + { + if (((Q >> 1) & 3) == 3) + { + q2 = 4; + C = (((Q >> 3) & 3) << 3) | ((~(Q >> 5) & 3) << 1) | (Q & 1); + } + else + { + q2 = (Q >> 5) & 3; + C = Q & 0x1f; + } + + if ((C & 7) == 5) + { + q1 = 4; + q0 = (C >> 3) & 3; + } + else + { + q1 = (C >> 3) & 3; + q0 = C & 7; + } + } + + trits_quints[256 + Q] = q0 | (q1 << 3) | (q2 << 6); + } +} +} diff --git a/src/mesa/main/texcompress_astc_luts.h b/src/mesa/main/texcompress_astc_luts.h new file mode 100644 index 00000000000..b3c26033a9a --- /dev/null +++ b/src/mesa/main/texcompress_astc_luts.h @@ -0,0 +1,127 @@ +/* Copyright (c) 2017-2022 Hans-Kristian Arntzen + * + * 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 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. + */ + +#pragma once + +#include +#include +#include + +namespace Granite +{ + +struct ASTCQuantizationMode +{ + uint8_t bits, trits, quints; +}; + +// In order to decode color endpoints, we need to convert available bits and number of values +// into a format of (bits, trits, quints). A simple LUT texture is a reasonable approach for this. +// Decoders are expected to have some form of LUT to deal with this ... +static const ASTCQuantizationMode astc_quantization_modes[] = { + { 8, 0, 0 }, + { 6, 1, 0 }, + { 5, 0, 1 }, + { 7, 0, 0 }, + { 5, 1, 0 }, + { 4, 0, 1 }, + { 6, 0, 0 }, + { 4, 1, 0 }, + { 3, 0, 1 }, + { 5, 0, 0 }, + { 3, 1, 0 }, + { 2, 0, 1 }, + { 4, 0, 0 }, + { 2, 1, 0 }, + { 1, 0, 1 }, + { 3, 0, 0 }, + { 1, 1, 0 }, +}; + +constexpr size_t astc_num_quantization_modes = sizeof(astc_quantization_modes) / sizeof(astc_quantization_modes[0]); + +static const ASTCQuantizationMode astc_weight_modes[] = { + { 0, 0, 0 }, // Invalid + { 0, 0, 0 }, // Invalid + { 1, 0, 0 }, + { 0, 1, 0 }, + { 2, 0, 0 }, + { 0, 0, 1 }, + { 1, 1, 0 }, + { 3, 0, 0 }, + { 0, 0, 0 }, // Invalid + { 0, 0, 0 }, // Invalid + { 1, 0, 1 }, + { 2, 1, 0 }, + { 4, 0, 0 }, + { 2, 0, 1 }, + { 3, 1, 0 }, + { 5, 0, 0 }, +}; + +constexpr size_t astc_num_weight_modes = sizeof(astc_weight_modes) / sizeof(astc_weight_modes[0]); + +struct ASTCLutHolder +{ + ASTCLutHolder(); + + void init_color_endpoint(); + void init_weight_luts(); + void init_trits_quints(); + + struct + { + size_t unquant_offset = 0; + uint8_t unquant_lut[2048]; + uint16_t lut[9][128][4]; + size_t unquant_lut_offsets[astc_num_quantization_modes]; + } color_endpoint; + + struct + { + size_t unquant_offset = 0; + uint8_t unquant_lut[2048]; + uint8_t lut[astc_num_weight_modes][4]; + } weights; + + struct + { + uint16_t trits_quints[256 + 128]; + } integer; + + struct PartitionTable + { + PartitionTable() = default; + PartitionTable(unsigned width, unsigned height); + std::vector lut_buffer; + unsigned lut_width = 0; + unsigned lut_height = 0; + }; + + std::mutex table_lock; + std::unordered_map tables; + + PartitionTable &get_partition_table(unsigned width, unsigned height); +}; + +ASTCLutHolder &get_astc_luts(); +} diff --git a/src/mesa/main/texcompress_astc_luts_wrap.cpp b/src/mesa/main/texcompress_astc_luts_wrap.cpp new file mode 100644 index 00000000000..a02dad7bc47 --- /dev/null +++ b/src/mesa/main/texcompress_astc_luts_wrap.cpp @@ -0,0 +1,65 @@ +/* + * Copyright © 2022 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 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 "texcompress_astc_luts_wrap.h" +#include "texcompress_astc_luts.h" + +#include "util/u_box.h" + +extern "C" void +_mesa_init_astc_decoder_luts(astc_decoder_lut_holder *holder) +{ + auto &luts = Granite::get_astc_luts(); + + holder->color_endpoint.data = luts.color_endpoint.lut; + holder->color_endpoint.size_B = sizeof(luts.color_endpoint.lut); + holder->color_endpoint.format = PIPE_FORMAT_R16G16B16A16_UINT; + + holder->color_endpoint_unquant.data = luts.color_endpoint.unquant_lut; + holder->color_endpoint_unquant.size_B = luts.color_endpoint.unquant_offset; + holder->color_endpoint_unquant.format = PIPE_FORMAT_R8_UINT; + + holder->weights.data = luts.weights.lut; + holder->weights.size_B = sizeof(luts.weights.lut); + holder->weights.format = PIPE_FORMAT_R8G8B8A8_UINT; + + holder->weights_unquant.data = luts.weights.unquant_lut; + holder->weights_unquant.size_B = luts.weights.unquant_offset; + holder->weights_unquant.format = PIPE_FORMAT_R8_UINT; + + holder->trits_quints.data = luts.integer.trits_quints; + holder->trits_quints.size_B = sizeof(luts.integer.trits_quints); + holder->trits_quints.format = PIPE_FORMAT_R16_UINT; +} + +extern "C" void * +_mesa_get_astc_decoder_partition_table(uint32_t block_width, + uint32_t block_height, + struct pipe_box *ptable_box) +{ + auto &luts = Granite::get_astc_luts(); + auto &table = luts.get_partition_table(block_width, block_height); + + u_box_origin_2d(table.lut_width, table.lut_height, ptable_box); + + return table.lut_buffer.data(); +} diff --git a/src/mesa/main/texcompress_astc_luts_wrap.h b/src/mesa/main/texcompress_astc_luts_wrap.h new file mode 100644 index 00000000000..e78f81054ad --- /dev/null +++ b/src/mesa/main/texcompress_astc_luts_wrap.h @@ -0,0 +1,62 @@ +/* + * Copyright © 2022 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 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_ASTC_LUTS_WRAP_H +#define TEXCOMPRESS_ASTC_LUTS_WRAP_H + +#include +#include "pipe/p_state.h" + +/* C wrapper for Granite::ASTCLutHolder. */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_box; + +typedef struct +{ + void *data; + size_t size_B; + enum pipe_format format; +} astc_decoder_lut; + +typedef struct +{ + astc_decoder_lut color_endpoint; + astc_decoder_lut color_endpoint_unquant; + astc_decoder_lut weights; + astc_decoder_lut weights_unquant; + astc_decoder_lut trits_quints; +} astc_decoder_lut_holder; + +void _mesa_init_astc_decoder_luts(astc_decoder_lut_holder *holder); +void *_mesa_get_astc_decoder_partition_table(uint32_t block_width, + uint32_t block_height, + struct pipe_box *ptable_box); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/meson.build b/src/mesa/meson.build index 7af2fac8af9..b7a67ccc5e5 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -205,6 +205,10 @@ files_libmesa = files( 'main/texcompress.h', 'main/texcompress_astc.cpp', 'main/texcompress_astc.h', + 'main/texcompress_astc_luts.cpp', + 'main/texcompress_astc_luts.h', + 'main/texcompress_astc_luts_wrap.cpp', + 'main/texcompress_astc_luts_wrap.h', 'main/texcompress_bptc.c', 'main/texcompress_bptc.h', 'main/texcompress_cpal.c',