diff options
Diffstat (limited to 'thirdparty/astcenc/astcenc_find_best_partitioning.cpp')
-rw-r--r-- | thirdparty/astcenc/astcenc_find_best_partitioning.cpp | 57 |
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); |