Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/basis_universal/transcoder/basisu_transcoder_uastc.h
9905 views
1
// basisu_transcoder_uastc.h
2
#pragma once
3
#include "basisu_transcoder_internal.h"
4
5
namespace basist
6
{
7
struct color_quad_u8
8
{
9
uint8_t m_c[4];
10
};
11
12
const uint32_t TOTAL_UASTC_MODES = 19;
13
const uint32_t UASTC_MODE_INDEX_SOLID_COLOR = 8;
14
15
const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS2 = 30;
16
const uint32_t TOTAL_ASTC_BC6H_COMMON_PARTITIONS2 = 27; // BC6H only supports only 5-bit pattern indices, BC7 supports 4-bit or 6-bit
17
const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS3 = 11;
18
const uint32_t TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS = 19;
19
20
extern const uint8_t g_uastc_mode_weight_bits[TOTAL_UASTC_MODES];
21
extern const uint8_t g_uastc_mode_weight_ranges[TOTAL_UASTC_MODES];
22
extern const uint8_t g_uastc_mode_endpoint_ranges[TOTAL_UASTC_MODES];
23
extern const uint8_t g_uastc_mode_subsets[TOTAL_UASTC_MODES];
24
extern const uint8_t g_uastc_mode_planes[TOTAL_UASTC_MODES];
25
extern const uint8_t g_uastc_mode_comps[TOTAL_UASTC_MODES];
26
extern const uint8_t g_uastc_mode_has_etc1_bias[TOTAL_UASTC_MODES];
27
extern const uint8_t g_uastc_mode_has_bc1_hint0[TOTAL_UASTC_MODES];
28
extern const uint8_t g_uastc_mode_has_bc1_hint1[TOTAL_UASTC_MODES];
29
extern const uint8_t g_uastc_mode_has_alpha[TOTAL_UASTC_MODES];
30
extern const uint8_t g_uastc_mode_is_la[TOTAL_UASTC_MODES];
31
32
struct astc_bc7_common_partition2_desc
33
{
34
uint8_t m_bc7;
35
uint16_t m_astc;
36
bool m_invert;
37
};
38
39
extern const astc_bc7_common_partition2_desc g_astc_bc7_common_partitions2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2];
40
41
struct bc73_astc2_common_partition_desc
42
{
43
uint8_t m_bc73;
44
uint16_t m_astc2;
45
uint8_t k; // 0-5 - how to modify the BC7 3-subset pattern to match the ASTC pattern (LSB=invert)
46
};
47
48
extern const bc73_astc2_common_partition_desc g_bc7_3_astc2_common_partitions[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS];
49
50
struct astc_bc7_common_partition3_desc
51
{
52
uint8_t m_bc7;
53
uint16_t m_astc;
54
uint8_t m_astc_to_bc7_perm; // converts ASTC to BC7 partition using g_astc_bc7_partition_index_perm_tables[][]
55
};
56
57
extern const astc_bc7_common_partition3_desc g_astc_bc7_common_partitions3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3];
58
59
extern const uint8_t g_astc_bc7_patterns2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][16];
60
extern const uint8_t g_astc_bc7_patterns3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][16];
61
extern const uint8_t g_bc7_3_astc2_patterns2[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][16];
62
63
extern const uint8_t g_astc_bc7_pattern2_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][3];
64
extern const uint8_t g_astc_bc7_pattern3_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][3];
65
extern const uint8_t g_bc7_3_astc2_patterns2_anchors[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][3];
66
67
extern const uint32_t g_uastc_mode_huff_codes[TOTAL_UASTC_MODES + 1][2];
68
69
extern const uint8_t g_astc_to_bc7_partition_index_perm_tables[6][3];
70
extern const uint8_t g_bc7_to_astc_partition_index_perm_tables[6][3]; // inverse of g_astc_to_bc7_partition_index_perm_tables
71
72
extern const uint8_t* s_uastc_to_bc1_weights[6];
73
74
uint32_t bc7_convert_partition_index_3_to_2(uint32_t p, uint32_t k);
75
76
inline uint32_t astc_interpolate(uint32_t l, uint32_t h, uint32_t w, bool srgb)
77
{
78
if (srgb)
79
{
80
l = (l << 8) | 0x80;
81
h = (h << 8) | 0x80;
82
}
83
else
84
{
85
l = (l << 8) | l;
86
h = (h << 8) | h;
87
}
88
89
uint32_t k = (l * (64 - w) + h * w + 32) >> 6;
90
91
return k >> 8;
92
}
93
94
struct astc_block_desc
95
{
96
int m_weight_range; // weight BISE range
97
98
int m_subsets; // number of ASTC partitions
99
int m_partition_seed; // partition pattern seed
100
int m_cem; // color endpoint mode used by all subsets
101
102
int m_ccs; // color component selector (dual plane only)
103
bool m_dual_plane; // true if dual plane
104
105
// Weight and endpoint BISE values.
106
// Note these values are NOT linear, they must be BISE encoded. See Table 97 and Table 107.
107
uint8_t m_endpoints[18]; // endpoint values, in RR GG BB etc. order
108
uint8_t m_weights[64]; // weight index values, raster order, in P0 P1, P0 P1, etc. or P0, P0, P0, P0, etc. order
109
};
110
111
const uint32_t BC7ENC_TOTAL_ASTC_RANGES = 21;
112
113
// See tables 81, 93, 18.13.Endpoint Unquantization
114
const uint32_t TOTAL_ASTC_RANGES = 21;
115
extern const int g_astc_bise_range_table[TOTAL_ASTC_RANGES][3];
116
117
struct astc_quant_bin
118
{
119
uint8_t m_unquant; // unquantized value
120
uint8_t m_index; // sorted index
121
};
122
123
extern astc_quant_bin g_astc_unquant[BC7ENC_TOTAL_ASTC_RANGES][256]; // [ASTC encoded endpoint index]
124
125
int astc_get_levels(int range);
126
bool astc_is_valid_endpoint_range(uint32_t range);
127
uint32_t unquant_astc_endpoint(uint32_t packed_bits, uint32_t packed_trits, uint32_t packed_quints, uint32_t range);
128
uint32_t unquant_astc_endpoint_val(uint32_t packed_val, uint32_t range);
129
130
const uint8_t* get_anchor_indices(uint32_t subsets, uint32_t mode, uint32_t common_pattern, const uint8_t*& pPartition_pattern);
131
132
// BC7
133
const uint32_t BC7ENC_BLOCK_SIZE = 16;
134
135
struct bc7_block
136
{
137
uint64_t m_qwords[2];
138
};
139
140
struct bc7_optimization_results
141
{
142
uint32_t m_mode;
143
uint32_t m_partition;
144
uint8_t m_selectors[16];
145
uint8_t m_alpha_selectors[16];
146
color_quad_u8 m_low[3];
147
color_quad_u8 m_high[3];
148
uint32_t m_pbits[3][2];
149
uint32_t m_index_selector;
150
uint32_t m_rotation;
151
};
152
153
extern const uint32_t g_bc7_weights1[2];
154
extern const uint32_t g_bc7_weights2[4];
155
extern const uint32_t g_bc7_weights3[8];
156
extern const uint32_t g_bc7_weights4[16];
157
extern const uint32_t g_astc_weights4[16];
158
extern const uint32_t g_astc_weights5[32];
159
extern const uint32_t g_astc_weights_3levels[3];
160
extern const uint8_t g_bc7_partition1[16];
161
extern const uint8_t g_bc7_partition2[64 * 16];
162
extern const uint8_t g_bc7_partition3[64 * 16];
163
extern const uint8_t g_bc7_table_anchor_index_second_subset[64];
164
extern const uint8_t g_bc7_table_anchor_index_third_subset_1[64];
165
extern const uint8_t g_bc7_table_anchor_index_third_subset_2[64];
166
extern const uint8_t g_bc7_num_subsets[8];
167
extern const uint8_t g_bc7_partition_bits[8];
168
extern const uint8_t g_bc7_color_index_bitcount[8];
169
extern const uint8_t g_bc7_mode_has_p_bits[8];
170
extern const uint8_t g_bc7_mode_has_shared_p_bits[8];
171
extern const uint8_t g_bc7_color_precision_table[8];
172
extern const int8_t g_bc7_alpha_precision_table[8];
173
extern const uint8_t g_bc7_alpha_index_bitcount[8];
174
175
inline bool get_bc7_mode_has_seperate_alpha_selectors(int mode) { return (mode == 4) || (mode == 5); }
176
inline int get_bc7_color_index_size(int mode, int index_selection_bit) { return g_bc7_color_index_bitcount[mode] + index_selection_bit; }
177
inline int get_bc7_alpha_index_size(int mode, int index_selection_bit) { return g_bc7_alpha_index_bitcount[mode] - index_selection_bit; }
178
179
struct endpoint_err
180
{
181
uint16_t m_error; uint8_t m_lo; uint8_t m_hi;
182
};
183
184
extern endpoint_err g_bc7_mode_6_optimal_endpoints[256][2]; // [c][pbit]
185
const uint32_t BC7ENC_MODE_6_OPTIMAL_INDEX = 5;
186
187
extern endpoint_err g_bc7_mode_5_optimal_endpoints[256]; // [c]
188
const uint32_t BC7ENC_MODE_5_OPTIMAL_INDEX = 1;
189
190
// Packs a BC7 block from a high-level description. Handles all BC7 modes.
191
void encode_bc7_block(void* pBlock, const bc7_optimization_results* pResults);
192
193
// Packs an ASTC block
194
// Constraints: Always 4x4, all subset CEM's must be equal, only tested with LDR CEM's.
195
bool pack_astc_block(uint32_t* pDst, const astc_block_desc* pBlock, uint32_t mode);
196
197
void pack_astc_solid_block(void* pDst_block, const color32& color);
198
199
#ifdef _DEBUG
200
int astc_compute_texel_partition(int seed, int x, int y, int z, int partitioncount, bool small_block);
201
#endif
202
203
struct uastc_block
204
{
205
union
206
{
207
uint8_t m_bytes[16];
208
uint32_t m_dwords[4];
209
};
210
};
211
212
struct unpacked_uastc_block
213
{
214
astc_block_desc m_astc;
215
216
uint32_t m_mode;
217
uint32_t m_common_pattern;
218
219
color32 m_solid_color;
220
221
bool m_bc1_hint0;
222
bool m_bc1_hint1;
223
224
bool m_etc1_flip;
225
bool m_etc1_diff;
226
uint32_t m_etc1_inten0;
227
uint32_t m_etc1_inten1;
228
229
uint32_t m_etc1_bias;
230
231
uint32_t m_etc2_hints;
232
233
uint32_t m_etc1_selector;
234
uint32_t m_etc1_r, m_etc1_g, m_etc1_b;
235
};
236
237
color32 apply_etc1_bias(const color32 &block_color, uint32_t bias, uint32_t limit, uint32_t subblock);
238
239
struct decoder_etc_block;
240
struct eac_block;
241
242
bool unpack_uastc(uint32_t mode, uint32_t common_pattern, const color32& solid_color, const astc_block_desc& astc, color32* pPixels, bool srgb);
243
bool unpack_uastc(const unpacked_uastc_block& unpacked_blk, color32* pPixels, bool srgb);
244
245
bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb);
246
bool unpack_uastc(const uastc_block& blk, unpacked_uastc_block& unpacked, bool undo_blue_contract, bool read_hints = true);
247
248
bool transcode_uastc_to_astc(const uastc_block& src_blk, void* pDst);
249
250
bool transcode_uastc_to_bc7(const unpacked_uastc_block& unpacked_src_blk, bc7_optimization_results& dst_blk);
251
bool transcode_uastc_to_bc7(const uastc_block& src_blk, bc7_optimization_results& dst_blk);
252
bool transcode_uastc_to_bc7(const uastc_block& src_blk, void* pDst);
253
254
void transcode_uastc_to_etc1(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst);
255
bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst);
256
bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst, uint32_t channel);
257
258
void transcode_uastc_to_etc2_eac_a8(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst);
259
bool transcode_uastc_to_etc2_rgba(const uastc_block& src_blk, void* pDst);
260
261
// Packs 16 scalar values to BC4. Same PSNR as stb_dxt's BC4 encoder, around 13% faster.
262
void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride);
263
264
void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb);
265
266
enum
267
{
268
cEncodeBC1HighQuality = 1,
269
cEncodeBC1HigherQuality = 2,
270
cEncodeBC1UseSelectors = 4,
271
};
272
void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags);
273
274
// Alternate PCA-free encoder, around 15% faster, same (or slightly higher) avg. PSNR
275
void encode_bc1_alt(void* pDst, const uint8_t* pPixels, uint32_t flags);
276
277
void transcode_uastc_to_bc1_hint0(const unpacked_uastc_block& unpacked_src_blk, void* pDst);
278
void transcode_uastc_to_bc1_hint1(const unpacked_uastc_block& unpacked_src_blk, const color32 block_pixels[4][4], void* pDst, bool high_quality);
279
280
bool transcode_uastc_to_bc1(const uastc_block& src_blk, void* pDst, bool high_quality);
281
bool transcode_uastc_to_bc3(const uastc_block& src_blk, void* pDst, bool high_quality);
282
bool transcode_uastc_to_bc4(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0);
283
bool transcode_uastc_to_bc5(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1);
284
285
bool transcode_uastc_to_etc2_eac_r11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0);
286
bool transcode_uastc_to_etc2_eac_rg11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1);
287
288
bool transcode_uastc_to_pvrtc1_4_rgb(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality, bool from_alpha);
289
bool transcode_uastc_to_pvrtc1_4_rgba(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality);
290
291
// uastc_init() MUST be called before using this module.
292
void uastc_init();
293
294
} // namespace basist
295
296