summaryrefslogtreecommitdiffstats
path: root/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/astcenc/astcenc_find_best_partitioning.cpp')
-rw-r--r--thirdparty/astcenc/astcenc_find_best_partitioning.cpp57
1 files changed, 35 insertions, 22 deletions
diff --git a/thirdparty/astcenc/astcenc_find_best_partitioning.cpp b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
index 789c3964ef..bfbcc35e94 100644
--- a/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
+++ b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
@@ -250,13 +250,16 @@ static void kmeans_update(
*
* @return The number of bit mismatches.
*/
-static inline unsigned int partition_mismatch2(
+static inline uint8_t partition_mismatch2(
const uint64_t a[2],
const uint64_t b[2]
) {
int v1 = popcount(a[0] ^ b[0]) + popcount(a[1] ^ b[1]);
int v2 = popcount(a[0] ^ b[1]) + popcount(a[1] ^ b[0]);
- return astc::min(v1, v2);
+
+ // Divide by 2 because XOR always counts errors twice, once when missing
+ // in the expected position, and again when present in the wrong partition
+ return static_cast<uint8_t>(astc::min(v1, v2) / 2);
}
/**
@@ -267,7 +270,7 @@ static inline unsigned int partition_mismatch2(
*
* @return The number of bit mismatches.
*/
-static inline unsigned int partition_mismatch3(
+static inline uint8_t partition_mismatch3(
const uint64_t a[3],
const uint64_t b[3]
) {
@@ -295,7 +298,9 @@ static inline unsigned int partition_mismatch3(
int s5 = p11 + p20;
int v2 = astc::min(s4, s5) + p02;
- return astc::min(v0, v1, v2);
+ // Divide by 2 because XOR always counts errors twice, once when missing
+ // in the expected position, and again when present in the wrong partition
+ return static_cast<uint8_t>(astc::min(v0, v1, v2) / 2);
}
/**
@@ -306,7 +311,7 @@ static inline unsigned int partition_mismatch3(
*
* @return The number of bit mismatches.
*/
-static inline unsigned int partition_mismatch4(
+static inline uint8_t partition_mismatch4(
const uint64_t a[4],
const uint64_t b[4]
) {
@@ -342,7 +347,9 @@ static inline unsigned int partition_mismatch4(
int v2 = p02 + astc::min(p11 + mx03, p10 + mx13, p13 + mx01);
int v3 = p03 + astc::min(p11 + mx02, p12 + mx01, p10 + mx12);
- return astc::min(v0, v1, v2, v3);
+ // Divide by 2 because XOR always counts errors twice, once when missing
+ // in the expected position, and again when present in the wrong partition
+ return static_cast<uint8_t>(astc::min(v0, v1, v2, v3) / 2);
}
using mismatch_dispatch = unsigned int (*)(const uint64_t*, const uint64_t*);
@@ -359,7 +366,7 @@ static void count_partition_mismatch_bits(
const block_size_descriptor& bsd,
unsigned int partition_count,
const uint64_t bitmaps[BLOCK_MAX_PARTITIONS],
- unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS]
+ uint8_t mismatch_counts[BLOCK_MAX_PARTITIONINGS]
) {
unsigned int active_count = bsd.partitioning_count_selected[partition_count - 1];
promise(active_count > 0);
@@ -369,6 +376,8 @@ static void count_partition_mismatch_bits(
for (unsigned int i = 0; i < active_count; i++)
{
mismatch_counts[i] = partition_mismatch2(bitmaps, bsd.coverage_bitmaps_2[i]);
+ assert(mismatch_counts[i] < BLOCK_MAX_KMEANS_TEXELS);
+ assert(mismatch_counts[i] < bsd.texel_count);
}
}
else if (partition_count == 3)
@@ -376,6 +385,8 @@ static void count_partition_mismatch_bits(
for (unsigned int i = 0; i < active_count; i++)
{
mismatch_counts[i] = partition_mismatch3(bitmaps, bsd.coverage_bitmaps_3[i]);
+ assert(mismatch_counts[i] < BLOCK_MAX_KMEANS_TEXELS);
+ assert(mismatch_counts[i] < bsd.texel_count);
}
}
else
@@ -383,6 +394,8 @@ static void count_partition_mismatch_bits(
for (unsigned int i = 0; i < active_count; i++)
{
mismatch_counts[i] = partition_mismatch4(bitmaps, bsd.coverage_bitmaps_4[i]);
+ assert(mismatch_counts[i] < BLOCK_MAX_KMEANS_TEXELS);
+ assert(mismatch_counts[i] < bsd.texel_count);
}
}
}
@@ -397,12 +410,13 @@ static void count_partition_mismatch_bits(
* @return The number of active partitions in this selection.
*/
static unsigned int get_partition_ordering_by_mismatch_bits(
+ unsigned int texel_count,
unsigned int partitioning_count,
- const unsigned int mismatch_count[BLOCK_MAX_PARTITIONINGS],
- unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS]
+ const uint8_t mismatch_count[BLOCK_MAX_PARTITIONINGS],
+ uint16_t partition_ordering[BLOCK_MAX_PARTITIONINGS]
) {
promise(partitioning_count > 0);
- unsigned int mscount[256] { 0 };
+ uint16_t mscount[BLOCK_MAX_KMEANS_TEXELS] { 0 };
// Create the histogram of mismatch counts
for (unsigned int i = 0; i < partitioning_count; i++)
@@ -410,16 +424,14 @@ static unsigned int get_partition_ordering_by_mismatch_bits(
mscount[mismatch_count[i]]++;
}
- unsigned int active_count = partitioning_count - mscount[255];
-
// Create a running sum from the histogram array
// Cells store previous values only; i.e. exclude self after sum
- unsigned int summa = 0;
- for (unsigned int i = 0; i < 256; i++)
+ unsigned int sum = 0;
+ for (unsigned int i = 0; i < texel_count; i++)
{
- unsigned int cnt = mscount[i];
- mscount[i] = summa;
- summa += cnt;
+ uint16_t cnt = mscount[i];
+ mscount[i] = sum;
+ sum += cnt;
}
// Use the running sum as the index, incrementing after read to allow
@@ -427,10 +439,10 @@ static unsigned int get_partition_ordering_by_mismatch_bits(
for (unsigned int i = 0; i < partitioning_count; i++)
{
unsigned int idx = mscount[mismatch_count[i]]++;
- partition_ordering[idx] = i;
+ partition_ordering[idx] = static_cast<uint16_t>(i);
}
- return active_count;
+ return partitioning_count;
}
/**
@@ -447,7 +459,7 @@ static unsigned int compute_kmeans_partition_ordering(
const block_size_descriptor& bsd,
const image_block& blk,
unsigned int partition_count,
- unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS]
+ uint16_t partition_ordering[BLOCK_MAX_PARTITIONINGS]
) {
vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS];
uint8_t texel_partitions[BLOCK_MAX_TEXELS];
@@ -478,11 +490,12 @@ static unsigned int compute_kmeans_partition_ordering(
}
// Count the mismatch between the block and the format's partition tables
- unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS];
+ uint8_t mismatch_counts[BLOCK_MAX_PARTITIONINGS];
count_partition_mismatch_bits(bsd, partition_count, bitmaps, mismatch_counts);
// Sort the partitions based on the number of mismatched bits
return get_partition_ordering_by_mismatch_bits(
+ texels_to_process,
bsd.partitioning_count_selected[partition_count - 1],
mismatch_counts, partition_ordering);
}
@@ -565,7 +578,7 @@ unsigned int find_best_partition_candidates(
weight_imprecision_estim = weight_imprecision_estim * weight_imprecision_estim;
- unsigned int partition_sequence[BLOCK_MAX_PARTITIONINGS];
+ uint16_t partition_sequence[BLOCK_MAX_PARTITIONINGS];
unsigned int sequence_len = compute_kmeans_partition_ordering(bsd, blk, partition_count, partition_sequence);
partition_search_limit = astc::min(partition_search_limit, sequence_len);
requested_candidates = astc::min(partition_search_limit, requested_candidates);