API cleanup for pick_best_endpoint_format

This commit is contained in:
pete
2021-05-16 21:31:01 +01:00
parent 21ebff9d19
commit d4b6328b6c
4 changed files with 250 additions and 187 deletions
+17 -17
View File
@@ -367,15 +367,15 @@ static float compress_symbolic_block_fixed_partition_1plane(
// and weight encodings; return results for the 4 best-looking modes.
int partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][4];
int quantized_weight[TUNE_MAX_TRIAL_CANDIDATES];
int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES];
// TODO: Make these enums?
int color_quant_level[TUNE_MAX_TRIAL_CANDIDATES];
int color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES];
determine_optimal_set_of_endpoint_formats_to_use(
&bsd, pt, &blk, &ewb, &ei.ep, qwt_bitcounts, qwt_errors,
config.tune_candidate_limit, partition_format_specifiers, quantized_weight,
bsd, *pt, blk, ewb, ei.ep, qwt_bitcounts, qwt_errors,
config.tune_candidate_limit, partition_format_specifiers, block_mode_index,
color_quant_level, color_quant_level_mod);
// then iterate over the tune_candidate_limit believed-to-be-best modes to
@@ -389,21 +389,21 @@ static float compress_symbolic_block_fixed_partition_1plane(
uint8_t *u8_weight_src;
const int qw_packed_index = quantized_weight[i];
if (qw_packed_index < 0)
const int bm_packed_index = block_mode_index[i];
if (bm_packed_index < 0)
{
trace_add_data("failed", "error_block");
continue;
}
assert(qw_packed_index >= 0 && qw_packed_index < bsd.block_mode_count);
const block_mode& qw_bm = bsd.block_modes[qw_packed_index];
assert(bm_packed_index >= 0 && bm_packed_index < bsd.block_mode_count);
const block_mode& qw_bm = bsd.block_modes[bm_packed_index];
int decimation_mode = qw_bm.decimation_mode;
int weight_quant_mode = qw_bm.quant_mode;
const decimation_table& dt = *dts[decimation_mode];
promise(dt.weight_count > 0);
u8_weight_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * qw_packed_index;
u8_weight_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * bm_packed_index;
trace_add_data("weight_x", dt.weight_x);
trace_add_data("weight_y", dt.weight_y);
@@ -771,7 +771,7 @@ static float compress_symbolic_block_fixed_partition_2planes(
// decide the optimal combination of color endpoint encodings and weight encodings.
int partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][4];
int quantized_weight[TUNE_MAX_TRIAL_CANDIDATES];
int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES];
int color_quant_level[TUNE_MAX_TRIAL_CANDIDATES];
int color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES];
@@ -779,8 +779,8 @@ static float compress_symbolic_block_fixed_partition_2planes(
merge_endpoints(ei1.ep, ei2.ep, plane2_component, epm);
determine_optimal_set_of_endpoint_formats_to_use(
&bsd, pt, &blk, &ewb, &epm, qwt_bitcounts, qwt_errors,
config.tune_candidate_limit, partition_format_specifiers, quantized_weight,
bsd, *pt, blk, ewb, epm, qwt_bitcounts, qwt_errors,
config.tune_candidate_limit, partition_format_specifiers, block_mode_index,
color_quant_level, color_quant_level_mod);
// then iterate over the tune_candidate_limit believed-to-be-best modes to
@@ -792,8 +792,8 @@ static float compress_symbolic_block_fixed_partition_2planes(
{
TRACE_NODE(node0, "candidate");
const int qw_packed_index = quantized_weight[i];
if (qw_packed_index < 0)
const int bm_packed_index = block_mode_index[i];
if (bm_packed_index < 0)
{
trace_add_data("failed", "error_block");
continue;
@@ -802,16 +802,16 @@ static float compress_symbolic_block_fixed_partition_2planes(
uint8_t *u8_weight1_src;
uint8_t *u8_weight2_src;
assert(qw_packed_index >= 0 && qw_packed_index < bsd.block_mode_count);
const block_mode& qw_bm = bsd.block_modes[qw_packed_index];
assert(bm_packed_index >= 0 && bm_packed_index < bsd.block_mode_count);
const block_mode& qw_bm = bsd.block_modes[bm_packed_index];
int decimation_mode = qw_bm.decimation_mode;
int weight_quant_mode = qw_bm.quant_mode;
const decimation_table& dt = *dts[decimation_mode];
promise(dt.weight_count > 0);
u8_weight1_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * qw_packed_index);
u8_weight2_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * qw_packed_index + 1);
u8_weight1_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * bm_packed_index);
u8_weight2_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * bm_packed_index + 1);
trace_add_data("weight_x", dt.weight_x);
trace_add_data("weight_y", dt.weight_y);
+29 -11
View File
@@ -1507,21 +1507,39 @@ struct compress_symbolic_block_buffers
compress_fixed_partition_buffers planes;
};
/**
* @brief Identify, for each mode, which set of color endpoint produces the best result.
*
* Returns the best @c tune_candidate_limit best looking modes, along with the ideal color encoding
* combination for each. The modified quantization level can be used when all formats are the same,
* as this frees up two additional bits of storage.
*
* @param bsd The block size information.
* @param pi The partition info for the current trial.
* @param blk The image block color data to compress.
* @param ewb The image block weighted error data.
* @param ep The ideal endpoints.
* @param qwt_bitcounts Bit counts for different quantization methods.
* @param qwt_errors Errors for different quantization methods.
* @param tune_candidate_limit The number of candidates to return.
* @param[out] partition_format_specifiers The best formats per partition.
* @param[out] block_mode The best packed block mode index.
* @param[out] quant_level The best color quant level.
* @param[out] quant_level_mod The best color quant level if endpoints are the same.
*/
void determine_optimal_set_of_endpoint_formats_to_use(
const block_size_descriptor* bsd,
const partition_info* pt,
const imageblock* blk,
const error_weight_block* ewb,
const endpoints* ep,
// bitcounts and errors computed for the various quantization methods
const block_size_descriptor& bsd,
const partition_info& pi,
const imageblock& blk,
const error_weight_block& ewb,
const endpoints& ep,
const int* qwt_bitcounts,
const float* qwt_errors,
int tune_candidate_limit,
// output data
int partition_format_specifiers[4][4],
int quantized_weight[4],
int quant_level[4],
int quant_level_mod[4]);
int partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][4],
int block_mode[TUNE_MAX_TRIAL_CANDIDATES],
int quant_level[TUNE_MAX_TRIAL_CANDIDATES],
int quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES]);
/**
* @brief For a given 1 plane weight set recompute the endpoint colors.
+202 -158
View File
@@ -297,25 +297,31 @@ static void compute_encoding_choice_errors(
}
}
/*
functions to determine, for a given partitioning, which color endpoint formats are the best to use.
/**
* @brief For a given partition compute the error for every endpoint integer count and quant level.
*
* @param encode_hdr_rgb @c true if using HDR for RGB, @c false for LDR.
* @param encode_hdr_alpha @c true if using HDR for alpha, @c false for LDR.
* @param partition_index The partition index.
* @param pi The partition info.
* @param eci The encoding choice error metrics.
* @param ep The idealized endpoints.
* @param error_weight The resulting encoding choice error metrics.
* @param[out] best_error The best error for each integer count and quant level.
* @param[out] format_of_choice The preferred endpoint format for each integer count and quant level.
*/
// for a given partition, compute for every (integer-component-count, quantization-level)
// the color error.
static void compute_color_error_for_every_integer_count_and_quant_level(
int encode_hdr_rgb, // 1 = perform HDR encoding, 0 = perform LDR encoding.
int encode_hdr_alpha,
bool encode_hdr_rgb,
bool encode_hdr_alpha,
int partition_index,
const partition_info* pt,
const encoding_choice_errors* eci, // pointer to the structure for the CURRENT partition.
const endpoints* ep,
const partition_info& pi,
const encoding_choice_errors& eci,
const endpoints& ep,
vfloat4 error_weight,
// arrays to return results back through.
float best_error[21][4],
int format_of_choice[21][4]
) {
int partition_size = pt->partition_texel_count[partition_index];
int partition_size = pi.partition_texel_count[partition_index];
static const float baseline_quant_error[21] = {
(65536.0f * 65536.0f / 18.0f), // 2 values, 1 step
@@ -341,8 +347,8 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
(65536.0f * 65536.0f / 18.0f) / (255 * 255)
};
vfloat4 ep0 = ep->endpt0[partition_index];
vfloat4 ep1 = ep->endpt1[partition_index];
vfloat4 ep0 = ep.endpt0[partition_index];
vfloat4 ep1 = ep.endpt1[partition_index];
float ep1_min = hmin_rgb_s(ep1);
ep1_min = astc::max(ep1_min, 0.0f);
@@ -539,18 +545,18 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
format_of_choice[i][3] = encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA;
// for 6 integers, we have one HDR-RGB encoding
float full_hdr_rgb_error = (rgb_quantization_error * mode11mult) + rgb_range_error + eci->alpha_drop_error;
float full_hdr_rgb_error = (rgb_quantization_error * mode11mult) + rgb_range_error + eci.alpha_drop_error;
best_error[i][2] = full_hdr_rgb_error;
format_of_choice[i][2] = FMT_HDR_RGB;
// for 4 integers, we have one HDR-RGB-Scale encoding
float hdr_rgb_scale_error = (rgb_quantization_error * mode7mult) + rgb_range_error + eci->alpha_drop_error + eci->rgb_luma_error;
float hdr_rgb_scale_error = (rgb_quantization_error * mode7mult) + rgb_range_error + eci.alpha_drop_error + eci.rgb_luma_error;
best_error[i][1] = hdr_rgb_scale_error;
format_of_choice[i][1] = FMT_HDR_RGB_SCALE;
// for 2 integers, we assume luminance-with-large-range
float hdr_luminance_error = (rgb_quantization_error * mode23mult) + rgb_range_error + eci->alpha_drop_error + eci->luminance_error;
float hdr_luminance_error = (rgb_quantization_error * mode23mult) + rgb_range_error + eci.alpha_drop_error + eci.luminance_error;
best_error[i][0] = hdr_luminance_error;
format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE;
}
@@ -574,11 +580,11 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
float base_quant_error_a = error_weight.lane<3>() * static_cast<float>(partition_size);
float base_quant_error_rgba = base_quant_error_rgb + base_quant_error_a;
float error_scale_bc_rgba = eci->can_blue_contract ? 0.625f : 1.0f;
float error_scale_oe_rgba = eci->can_offset_encode ? 0.5f : 1.0f;
float error_scale_bc_rgba = eci.can_blue_contract ? 0.625f : 1.0f;
float error_scale_oe_rgba = eci.can_offset_encode ? 0.5f : 1.0f;
float error_scale_bc_rgb = eci->can_blue_contract ? 0.5f : 1.0f;
float error_scale_oe_rgb = eci->can_offset_encode ? 0.25f : 1.0f;
float error_scale_bc_rgb = eci.can_blue_contract ? 0.5f : 1.0f;
float error_scale_oe_rgb = eci.can_offset_encode ? 0.25f : 1.0f;
// pick among the available LDR endpoint modes
for (int i = 4; i < 21; i++)
@@ -609,10 +615,10 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
* error_scale_bc_rgb
* error_scale_oe_rgb
+ rgb_range_error
+ eci->alpha_drop_error;
+ eci.alpha_drop_error;
float rgbs_alpha_error = quant_error_rgba
+ eci->rgb_scale_error
+ eci.rgb_scale_error
+ rgb_range_error
+ alpha_range_error;
@@ -630,13 +636,13 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
// 4 integers can encode as RGBS or LA+LA
float ldr_rgbs_error = quant_error_rgb
+ rgb_range_error
+ eci->alpha_drop_error
+ eci->rgb_scale_error;
+ eci.alpha_drop_error
+ eci.rgb_scale_error;
float lum_alpha_error = quant_error_rgba
+ rgb_range_error
+ alpha_range_error
+ eci->luminance_error;
+ eci.luminance_error;
if (ldr_rgbs_error < lum_alpha_error)
{
@@ -652,8 +658,8 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
// 2 integers can encode as L+L
float luminance_error = quant_error_rgb
+ rgb_range_error
+ eci->alpha_drop_error
+ eci->luminance_error;
+ eci.alpha_drop_error
+ eci.luminance_error;
best_error[i][0] = luminance_error;
format_of_choice[i][0] = FMT_LUMINANCE;
@@ -661,14 +667,23 @@ static void compute_color_error_for_every_integer_count_and_quant_level(
}
}
// for 1 partition, find the best combination (one format + a quantization level) for a given bitcount
/**
* @brief For one partition compute the best format and quantization for a given bit count.
*
* @param best_combined_error The best error for each quant level and integer count.
* @param best_combined_format The best format for each quant level and integer count.
* @param bits_available The number of bits available for encoding.
* @param[out] best_quant_level The output best color quant level.
* @param[out] best_format The output best color format.
* @param[out] best_error The output error for the best pairing.
*/
static void one_partition_find_best_combination_for_bitcount(
float combined_best_error[21][4],
int formats_of_choice[21][4],
const float best_combined_error[21][4],
const int best_combined_format[21][4],
int bits_available,
int* best_quant_level,
int* best_formats,
float* error_of_best_combination
int& best_quant_level,
int& best_format,
float& best_error
) {
int best_integer_count = -1;
float best_integer_count_error = 1e20f;
@@ -682,39 +697,44 @@ static void one_partition_find_best_combination_for_bitcount(
continue; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all.
}
if (combined_best_error[quant_level][i] < best_integer_count_error)
if (best_combined_error[quant_level][i] < best_integer_count_error)
{
best_integer_count_error = combined_best_error[quant_level][i];
best_integer_count_error = best_combined_error[quant_level][i];
best_integer_count = i;
}
}
int ql = quant_mode_table[best_integer_count + 1][bits_available];
*best_quant_level = ql;
*error_of_best_combination = best_integer_count_error;
best_quant_level = ql;
best_format = FMT_LUMINANCE;
best_error = best_integer_count_error;
if (ql >= 0)
{
*best_formats = formats_of_choice[ql][best_integer_count];
}
else
{
*best_formats = FMT_LUMINANCE;
best_format = best_combined_format[ql][best_integer_count];
}
}
// for 2 partitions, find the best format combinations for every (quantization-mode, integer-count) combination
/**
* @brief For 2 partitions compute the best format combinations for every pair of quant mode and integer count.
*
* @param best_error The best error for a single endpoint quant level and integer count.
* @param best_format The best format for a single endpoint quant level and integer count.
* @param[out] best_combined_error The best combined error pairings for the 2 partitions.
* @param[out] best_combined_format The best combined format pairings for the 2 partitions.
*/
static void two_partitions_find_best_combination_for_every_quantization_and_integer_count(
float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1)
int format_of_choice[2][21][4],
float combined_best_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2)
int formats_of_choice[21][7][2]
const float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1)
const int best_format[2][21][4],
float best_combined_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2)
int best_combined_format[21][7][2]
) {
for (int i = 0; i < 21; i++)
{
for (int j = 0; j < 7; j++)
{
combined_best_error[i][j] = 1e30f;
best_combined_error[i][j] = 1e30f;
}
}
@@ -733,26 +753,36 @@ static void two_partitions_find_best_combination_for_every_quantization_and_inte
int intcnt = i + j;
float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j], 1e10f);
if (errorterm <= combined_best_error[quant][intcnt])
if (errorterm <= best_combined_error[quant][intcnt])
{
combined_best_error[quant][intcnt] = errorterm;
formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i];
formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j];
best_combined_error[quant][intcnt] = errorterm;
best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
}
}
}
}
}
// for 2 partitions, find the best combination (two formats + a quantization level) for a given bitcount
/**
* @brief For 2 partitions compute the best format and quantization for a given bit count.
*
* @param best_combined_error The best error for each quant level and integer count.
* @param best_combined_format The best format for each quant level and integer count.
* @param bits_available The number of bits available for encoding.
* @param[out] best_quant_level The output best color quant level.
* @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
* @param[out] best_formats The output best color formats.
* @param[out] best_error The output error for the best pairing.
*/
static void two_partitions_find_best_combination_for_bitcount(
float combined_best_error[21][7],
int formats_of_choice[21][7][2],
float best_combined_error[21][7],
int best_combined_format[21][7][2],
int bits_available,
int* best_quant_level,
int* best_quant_level_mod,
int& best_quant_level,
int& best_quant_level_mod,
int* best_formats,
float* error_of_best_combination
float& best_error
) {
int best_integer_count = 0;
float best_integer_count_error = 1e20f;
@@ -767,7 +797,7 @@ static void two_partitions_find_best_combination_for_bitcount(
break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all.
}
float integer_count_error = combined_best_error[quant_level][integer_count - 2];
float integer_count_error = best_combined_error[quant_level][integer_count - 2];
if (integer_count_error < best_integer_count_error)
{
@@ -779,14 +809,14 @@ static void two_partitions_find_best_combination_for_bitcount(
int ql = quant_mode_table[best_integer_count][bits_available];
int ql_mod = quant_mode_table[best_integer_count][bits_available + 2];
*best_quant_level = ql;
*best_quant_level_mod = ql_mod;
*error_of_best_combination = best_integer_count_error;
best_quant_level = ql;
best_quant_level_mod = ql_mod;
best_error = best_integer_count_error;
if (ql >= 0)
{
for (int i = 0; i < 2; i++)
{
best_formats[i] = formats_of_choice[ql][best_integer_count - 2][i];
best_formats[i] = best_combined_format[ql][best_integer_count - 2][i];
}
}
else
@@ -798,18 +828,25 @@ static void two_partitions_find_best_combination_for_bitcount(
}
}
// for 3 partitions, find the best format combinations for every (quantization-mode, integer-count) combination
/**
* @brief For 3 partitions compute the best format combinations for every pair of quant mode and integer count.
*
* @param best_error The best error for a single endpoint quant level and integer count.
* @param best_format The best format for a single endpoint quant level and integer count.
* @param[out] best_combined_error The best combined error pairings for the 3 partitions.
* @param[out] best_combined_format The best combined format pairings for the 3 partitions.
*/
static void three_partitions_find_best_combination_for_every_quantization_and_integer_count(
float best_error[3][21][4], // indexed by (partition, quant-level, integer-count)
int format_of_choice[3][21][4],
float combined_best_error[21][10],
int formats_of_choice[21][10][3]
const float best_error[3][21][4], // indexed by (partition, quant-level, integer-count)
const int best_format[3][21][4],
float best_combined_error[21][10],
int best_combined_format[21][10][3]
) {
for (int i = 0; i < 21; i++)
{
for (int j = 0; j < 10; j++)
{
combined_best_error[i][j] = 1e30f;
best_combined_error[i][j] = 1e30f;
}
}
@@ -837,12 +874,12 @@ static void three_partitions_find_best_combination_for_every_quantization_and_in
int intcnt = i + j + k;
float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k], 1e10f);
if (errorterm <= combined_best_error[quant][intcnt])
if (errorterm <= best_combined_error[quant][intcnt])
{
combined_best_error[quant][intcnt] = errorterm;
formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i];
formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j];
formats_of_choice[quant][intcnt][2] = format_of_choice[2][quant][k];
best_combined_error[quant][intcnt] = errorterm;
best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
best_combined_format[quant][intcnt][2] = best_format[2][quant][k];
}
}
}
@@ -850,15 +887,25 @@ static void three_partitions_find_best_combination_for_every_quantization_and_in
}
}
// for 3 partitions, find the best combination (three formats + a quantization level) for a given bitcount
/**
* @brief For 3 partitions compute the best format and quantization for a given bit count.
*
* @param best_combined_error The best error for each quant level and integer count.
* @param best_combined_format The best format for each quant level and integer count.
* @param bits_available The number of bits available for encoding.
* @param[out] best_quant_level The output best color quant level.
* @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
* @param[out] best_formats The output best color formats.
* @param[out] best_error The output error for the best pairing.
*/
static void three_partitions_find_best_combination_for_bitcount(
float combined_best_error[21][10],
int formats_of_choice[21][10][3],
const float best_combined_error[21][10],
const int best_combined_format[21][10][3],
int bits_available,
int* best_quant_level,
int* best_quant_level_mod,
int& best_quant_level,
int& best_quant_level_mod,
int* best_formats,
float* error_of_best_combination
float& best_error
) {
int best_integer_count = 0;
float best_integer_count_error = 1e20f;
@@ -873,7 +920,7 @@ static void three_partitions_find_best_combination_for_bitcount(
break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all.
}
float integer_count_error = combined_best_error[quant_level][integer_count - 3];
float integer_count_error = best_combined_error[quant_level][integer_count - 3];
if (integer_count_error < best_integer_count_error)
{
@@ -885,14 +932,14 @@ static void three_partitions_find_best_combination_for_bitcount(
int ql = quant_mode_table[best_integer_count][bits_available];
int ql_mod = quant_mode_table[best_integer_count][bits_available + 5];
*best_quant_level = ql;
*best_quant_level_mod = ql_mod;
*error_of_best_combination = best_integer_count_error;
best_quant_level = ql;
best_quant_level_mod = ql_mod;
best_error = best_integer_count_error;
if (ql >= 0)
{
for (int i = 0; i < 3; i++)
{
best_formats[i] = formats_of_choice[ql][best_integer_count - 3][i];
best_formats[i] = best_combined_format[ql][best_integer_count - 3][i];
}
}
else
@@ -904,18 +951,25 @@ static void three_partitions_find_best_combination_for_bitcount(
}
}
// for 4 partitions, find the best format combinations for every (quantization-mode, integer-count) combination
/**
* @brief For 4 partitions compute the best format combinations for every pair of quant mode and integer count.
*
* @param best_error The best error for a single endpoint quant level and integer count.
* @param best_format The best format for a single endpoint quant level and integer count.
* @param[out] best_combined_error The best combined error pairings for the 4 partitions.
* @param[out] best_combined_format The best combined format pairings for the 4 partitions.
*/
static void four_partitions_find_best_combination_for_every_quantization_and_integer_count(
float best_error[4][21][4], // indexed by (partition, quant-level, integer-count)
int format_of_choice[4][21][4],
float combined_best_error[21][13],
int formats_of_choice[21][13][4]
const float best_error[4][21][4], // indexed by (partition, quant-level, integer-count)
const int best_format[4][21][4],
float best_combined_error[21][13],
int best_combined_format[21][13][4]
) {
for (int i = 0; i < 21; i++)
{
for (int j = 0; j < 13; j++)
{
combined_best_error[i][j] = 1e30f;
best_combined_error[i][j] = 1e30f;
}
}
@@ -952,13 +1006,13 @@ static void four_partitions_find_best_combination_for_every_quantization_and_int
int intcnt = i + j + k + l;
float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k] + best_error[3][quant][l], 1e10f);
if (errorterm <= combined_best_error[quant][intcnt])
if (errorterm <= best_combined_error[quant][intcnt])
{
combined_best_error[quant][intcnt] = errorterm;
formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i];
formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j];
formats_of_choice[quant][intcnt][2] = format_of_choice[2][quant][k];
formats_of_choice[quant][intcnt][3] = format_of_choice[3][quant][l];
best_combined_error[quant][intcnt] = errorterm;
best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
best_combined_format[quant][intcnt][2] = best_format[2][quant][k];
best_combined_format[quant][intcnt][3] = best_format[3][quant][l];
}
}
}
@@ -967,15 +1021,25 @@ static void four_partitions_find_best_combination_for_every_quantization_and_int
}
}
// for 4 partitions, find the best combination (four formats + a quantization level) for a given bitcount
/**
* @brief For 4 partitions compute the best format and quantization for a given bit count.
*
* @param best_combined_error The best error for each quant level and integer count.
* @param best_combined_format The best format for each quant level and integer count.
* @param bits_available The number of bits available for encoding.
* @param[out] best_quant_level The output best color quant level.
* @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
* @param[out] best_formats The output best color formats.
* @param[out] best_error The output error for the best pairing.
*/
static void four_partitions_find_best_combination_for_bitcount(
float combined_best_error[21][13],
int formats_of_choice[21][13][4],
const float best_combined_error[21][13],
const int best_combined_format[21][13][4],
int bits_available,
int* best_quant_level,
int* best_quant_level_mod,
int& best_quant_level,
int& best_quant_level_mod,
int* best_formats,
float* error_of_best_combination
float& best_error
) {
int best_integer_count = 0;
float best_integer_count_error = 1e20f;
@@ -990,7 +1054,7 @@ static void four_partitions_find_best_combination_for_bitcount(
break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all.
}
float integer_count_error = combined_best_error[quant_level][integer_count - 4];
float integer_count_error = best_combined_error[quant_level][integer_count - 4];
if (integer_count_error < best_integer_count_error)
{
@@ -1002,14 +1066,14 @@ static void four_partitions_find_best_combination_for_bitcount(
int ql = quant_mode_table[best_integer_count][bits_available];
int ql_mod = quant_mode_table[best_integer_count][bits_available + 8];
*best_quant_level = ql;
*best_quant_level_mod = ql_mod;
*error_of_best_combination = best_integer_count_error;
best_quant_level = ql;
best_quant_level_mod = ql_mod;
best_error = best_integer_count_error;
if (ql >= 0)
{
for (int i = 0; i < 4; i++)
{
best_formats[i] = formats_of_choice[ql][best_integer_count - 4][i];
best_formats[i] = best_combined_format[ql][best_integer_count - 4][i];
}
}
else
@@ -1021,61 +1085,41 @@ static void four_partitions_find_best_combination_for_bitcount(
}
}
/*
The determine_optimal_set_of_endpoint_formats_to_use() function.
It identifies, for each mode, which set of color endpoint encodings
produces the best overall result. It then reports back which
tune_candidate_limit, modes look best, along with the ideal color encoding
combination for each.
It takes as input:
a partitioning an imageblock,
a set of color endpoints.
for each mode, the number of bits available for color encoding and the error incurred by quantization.
in case of 2 plane of weights, a specifier for which color component to use for the second plane of weights.
It delivers as output for each of the tune_candidate_limit selected modes:
format specifier
for each partition
quantization level to use
modified quantization level to use
(when all format specifiers are equal)
*/
/* See header for documentation. */
void determine_optimal_set_of_endpoint_formats_to_use(
const block_size_descriptor* bsd,
const partition_info* pt,
const imageblock* blk,
const error_weight_block* ewb,
const endpoints* ep,
const block_size_descriptor& bsd,
const partition_info& pi,
const imageblock& blk,
const error_weight_block& ewb,
const endpoints& ep,
// bitcounts and errors computed for the various quantization methods
const int* qwt_bitcounts,
const float* qwt_errors,
int tune_candidate_limit,
// output data
int partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][4],
int quantized_weight[TUNE_MAX_TRIAL_CANDIDATES],
int block_mode[TUNE_MAX_TRIAL_CANDIDATES],
int quant_level[TUNE_MAX_TRIAL_CANDIDATES],
int quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES]
) {
int partition_count = pt->partition_count;
int partition_count = pi.partition_count;
promise(partition_count > 0);
promise(bsd->block_mode_count > 0);
promise(bsd.block_mode_count > 0);
int encode_hdr_rgb = blk->rgb_lns[0];
int encode_hdr_alpha = blk->alpha_lns[0];
int encode_hdr_rgb = blk.rgb_lns[0];
int encode_hdr_alpha = blk.alpha_lns[0];
// call a helper function to compute the errors that result from various
// encoding choices (such as using luminance instead of RGB, discarding Alpha,
// using RGB-scale in place of two separate RGB endpoints and so on)
encoding_choice_errors eci[4];
compute_encoding_choice_errors(*bsd, *blk, *pt, *ewb, *ep, eci);
compute_encoding_choice_errors(bsd, blk, pi, ewb, ep, eci);
// for each partition, compute the error weights to apply for that partition.
partition_metrics pms[4];
compute_partition_error_color_weightings(*ewb, *pt, pms);
compute_partition_error_color_weightings(ewb, pi, pms);
float best_error[4][21][4];
int format_of_choice[4][21][4];
@@ -1083,7 +1127,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
{
compute_color_error_for_every_integer_count_and_quant_level(
encode_hdr_rgb, encode_hdr_alpha, i,
pt, &(eci[i]), ep, pms[i].error_weight, best_error[i],
pi, eci[i], ep, pms[i].error_weight, best_error[i],
format_of_choice[i]);
}
@@ -1094,7 +1138,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
// have to ensure that the "overstep" of the last iteration in the vectorized
// loop will contain data that will never be picked as best candidate
const int packed_mode_count = bsd->block_mode_count;
const int packed_mode_count = bsd.block_mode_count;
const int packed_mode_count_simd_up = round_up_to_simd_multiple_vla(packed_mode_count);
for (int i = packed_mode_count; i < packed_mode_count_simd_up; ++i)
{
@@ -1107,7 +1151,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
if (partition_count == 1)
{
float error_of_best_combination;
for (int i = 0; i < bsd->block_mode_count; ++i)
for (int i = 0; i < bsd.block_mode_count; ++i)
{
if (qwt_errors[i] >= 1e29f)
{
@@ -1117,7 +1161,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
one_partition_find_best_combination_for_bitcount(
best_error[0], format_of_choice[0], qwt_bitcounts[i],
best_quant_levels + i, best_ep_formats[i], &error_of_best_combination);
best_quant_levels[i], best_ep_formats[i][0], error_of_best_combination);
error_of_best_combination += qwt_errors[i];
errors_of_best_combination[i] = error_of_best_combination;
@@ -1134,7 +1178,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
best_error, format_of_choice, combined_best_error, formats_of_choice);
for (int i = 0; i < bsd->block_mode_count; ++i)
for (int i = 0; i < bsd.block_mode_count; ++i)
{
if (qwt_errors[i] >= 1e29f)
{
@@ -1145,8 +1189,8 @@ void determine_optimal_set_of_endpoint_formats_to_use(
float error_of_best_combination;
two_partitions_find_best_combination_for_bitcount(
combined_best_error, formats_of_choice, qwt_bitcounts[i],
best_quant_levels + i, best_quant_levels_mod + i,
best_ep_formats[i], &error_of_best_combination);
best_quant_levels[i], best_quant_levels_mod[i],
best_ep_formats[i], error_of_best_combination);
errors_of_best_combination[i] = error_of_best_combination + qwt_errors[i];
}
@@ -1160,7 +1204,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
three_partitions_find_best_combination_for_every_quantization_and_integer_count(
best_error, format_of_choice, combined_best_error, formats_of_choice);
for (int i = 0; i < bsd->block_mode_count; ++i)
for (int i = 0; i < bsd.block_mode_count; ++i)
{
if (qwt_errors[i] >= 1e29f)
{
@@ -1171,8 +1215,8 @@ void determine_optimal_set_of_endpoint_formats_to_use(
float error_of_best_combination;
three_partitions_find_best_combination_for_bitcount(
combined_best_error, formats_of_choice, qwt_bitcounts[i],
best_quant_levels + i, best_quant_levels_mod + i,
best_ep_formats[i], &error_of_best_combination);
best_quant_levels[i], best_quant_levels_mod[i],
best_ep_formats[i], error_of_best_combination);
errors_of_best_combination[i] = error_of_best_combination + qwt_errors[i];
}
@@ -1186,7 +1230,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
four_partitions_find_best_combination_for_every_quantization_and_integer_count(
best_error, format_of_choice, combined_best_error, formats_of_choice);
for (int i = 0; i < bsd->block_mode_count; ++i)
for (int i = 0; i < bsd.block_mode_count; ++i)
{
if (qwt_errors[i] >= 1e29f)
{
@@ -1197,8 +1241,8 @@ void determine_optimal_set_of_endpoint_formats_to_use(
float error_of_best_combination;
four_partitions_find_best_combination_for_bitcount(
combined_best_error, formats_of_choice, qwt_bitcounts[i],
best_quant_levels + i, best_quant_levels_mod + i,
best_ep_formats[i], &error_of_best_combination);
best_quant_levels[i], best_quant_levels_mod[i],
best_ep_formats[i], error_of_best_combination);
errors_of_best_combination[i] = error_of_best_combination + qwt_errors[i];
}
@@ -1211,7 +1255,7 @@ void determine_optimal_set_of_endpoint_formats_to_use(
vint vbest_error_index(-1);
vfloat vbest_ep_error(1e30f);
vint lane_ids = vint::lane_id();
for (int j = 0; j < bsd->block_mode_count; j += ASTCENC_SIMD_WIDTH)
for (int j = 0; j < bsd.block_mode_count; j += ASTCENC_SIMD_WIDTH)
{
vfloat err = vfloat(&errors_of_best_combination[j]);
vmask mask1 = err < vbest_ep_error;
@@ -1240,8 +1284,8 @@ void determine_optimal_set_of_endpoint_formats_to_use(
for (int i = 0; i < tune_candidate_limit; i++)
{
quantized_weight[i] = best_error_weights[i];
if (quantized_weight[i] >= 0)
block_mode[i] = best_error_weights[i];
if (block_mode[i] >= 0)
{
quant_level[i] = best_quant_levels[best_error_weights[i]];
assert(quant_level[i] >= 0 && quant_level[i] < 21);
+2 -1
View File
@@ -535,9 +535,10 @@ const uint8_t color_unquant_tables[21][256] = {
// The quant_mode_table[integercount/2][bits] gives us the quantization
// level for a given integer count and number of bits that the integer may fit
// into. This is needed for color decoding, and for the color encoding.
// into. This is needed for color encoding and decoding.
int8_t quant_mode_table[17][128];
/* See header for documentation. */
void build_quant_mode_table()
{
for (int i = 0; i <= 16; i++)