add stride; add calculate ssd

Signed-off-by: f00849353 <fanghuameng@huawei.com>
This commit is contained in:
f00849353
2023-11-15 11:26:52 +08:00
parent 90d5c405d9
commit d2a8f464ea
11 changed files with 181 additions and 14 deletions
+21
View File
@@ -162,6 +162,17 @@
#include <cstddef>
#include <cstdint>
#define QUALITY_CONTROL (1)
#if QUALITY_CONTROL
enum ComponentRGBA {
R_COM = 0,
G_COM,
B_COM,
A_COM,
RGBA_COM
};
#endif
#if defined(ASTCENC_DYNAMIC_LIBRARY)
#if defined(_MSC_VER)
#define ASTCENC_PUBLIC extern "C" __declspec(dllexport)
@@ -213,6 +224,9 @@ enum astcenc_error {
/** @brief The call failed due to an issue with diagnostic tracing. */
ASTCENC_ERR_DTRACE_FAILURE,
#endif
#if QUALITY_CONTROL
ASTCENC_ERR_BAD_QUALITY_CHECK
#endif
};
/**
@@ -541,6 +555,9 @@ struct astcenc_config
*/
struct astcenc_image
{
/** @brief The stride dimension of the image, in texels. */
unsigned int dim_stride;
/** @brief The X dimension of the image, in texels. */
unsigned int dim_x;
@@ -707,6 +724,10 @@ ASTCENC_PUBLIC astcenc_error astcenc_compress_image(
const astcenc_swizzle* swizzle,
uint8_t* data_out,
size_t data_len,
#if QUALITY_CONTROL
bool calQualityEnable,
int32_t *mse[RGBA_COM],
#endif
unsigned int thread_index);
/**
+30 -1
View File
@@ -1164,7 +1164,14 @@ void compress_block(
const astcenc_context& ctx,
const image_block& blk,
physical_compressed_block& pcb,
compression_working_buffers& tmpbuf)
#if QUALITY_CONTROL
compression_working_buffers& tmpbuf,
bool calQualityEnable,
int32_t *mseBlock[RGBA_COM]
#else
compression_working_buffers& tmpbuf
#endif
)
{
astcenc_profile decode_mode = ctx.config.profile;
symbolic_compressed_block scb;
@@ -1230,6 +1237,11 @@ void compress_block(
trace_add_data("exit", "quality hit");
symbolic_to_physical(bsd, scb, pcb);
#if QUALITY_CONTROL
if (calQualityEnable) {
*mseBlock[R_COM] = *mseBlock[G_COM] = *mseBlock[B_COM] = *mseBlock[A_COM];
}
#endif
return;
}
@@ -1416,6 +1428,23 @@ END_OF_TESTS:
// Compress to a physical block
symbolic_to_physical(bsd, scb, pcb);
#if QUALITY_CONTROL
if (calQualityEnable) {
image_block decBlk = blk;
decompress_symbolic_block(ctx.config.profile, bsd, blk.xpos, blk.ypos, blk.zpos, scb, decBlk);
vint4 colorSumDiff = vint4::zero();
for (size_t ii = 0; ii < bsd.texel_count; ii++) {
vint4 colorRef = float_to_int_rtn(blk.texel(ii) * 255.0f / 65535.0f);
vint4 colorTest = float_to_int_rtn(min(decBlk.texel(ii), 1.0f) * 255.0f);
vint4 colorDiff = colorRef - colorTest;
colorSumDiff += colorDiff * colorDiff;
}
*mseBlock[R_COM] = colorSumDiff.lane<0>();
*mseBlock[G_COM] = colorSumDiff.lane<1>();
*mseBlock[B_COM] = colorSumDiff.lane<2>();
*mseBlock[A_COM] = colorSumDiff.lane<3>();
}
#endif
}
#endif
+4 -4
View File
@@ -182,10 +182,10 @@ static void compute_pixel_region_variance(
int x_src = (x - 1) + offset_x - kernel_radius_xy;
x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1));
data[0] = data8[(4 * img->dim_x * y_src) + (4 * x_src )];
data[1] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 1)];
data[2] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 2)];
data[3] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 3)];
data[0] = data8[(4 * img->dim_stride * y_src) + (4 * x_src )];
data[1] = data8[(4 * img->dim_stride * y_src) + (4 * x_src + 1)];
data[2] = data8[(4 * img->dim_stride * y_src) + (4 * x_src + 2)];
data[3] = data8[(4 * img->dim_stride * y_src) + (4 * x_src + 3)];
uint8_t r = data[swz.r];
uint8_t g = data[swz.g];
+26 -2
View File
@@ -806,7 +806,13 @@ static void compress_image(
unsigned int thread_index,
const astcenc_image& image,
const astcenc_swizzle& swizzle,
#if QUALITY_CONTROL
uint8_t* buffer,
bool calQualityEnable,
int32_t *mse[RGBA_COM]
#else
uint8_t* buffer
#endif
) {
const block_size_descriptor& bsd = *ctx.bsd;
astcenc_profile decode_mode = ctx.config.profile;
@@ -932,7 +938,19 @@ static void compress_image(
int offset = ((z * yblocks + y) * xblocks + x) * 16;
uint8_t *bp = buffer + offset;
physical_compressed_block* pcb = reinterpret_cast<physical_compressed_block*>(bp);
#if QUALITY_CONTROL
int32_t *mseBlock[RGBA_COM] = {nullptr, nullptr, nullptr, nullptr};
if (calQualityEnable) {
int offset = (z * yblocks + y) * xblocks + x;
mseBlock[R_COM] = mse[R_COM] + offset;
mseBlock[G_COM] = mse[G_COM] + offset;
mseBlock[B_COM] = mse[B_COM] + offset;
mseBlock[A_COM] = mse[A_COM] + offset;
}
compress_block(ctx, blk, *pcb, temp_buffers, calQualityEnable, mseBlock);
#else
compress_block(ctx, blk, *pcb, temp_buffers);
#endif
}
ctx.manage_compress.complete_task_assignment(count);
@@ -948,6 +966,10 @@ astcenc_error astcenc_compress_image(
const astcenc_swizzle* swizzle,
uint8_t* data_out,
size_t data_len,
#if QUALITY_CONTROL
bool calQualityEnable,
int32_t *mse[RGBA_COM],
#endif
unsigned int thread_index
) {
#if defined(ASTCENC_DECOMPRESS_ONLY)
@@ -1022,9 +1044,11 @@ astcenc_error astcenc_compress_image(
// Wait for compute_averages to complete before compressing
ctx->manage_avg.wait();
#if QUALITY_CONTROL
compress_image(*ctx, thread_index, image, *swizzle, data_out, calQualityEnable, mse);
#else
compress_image(*ctx, thread_index, image, *swizzle, data_out);
#endif
// Wait for compress to complete before freeing memory
ctx->manage_compress.wait();
+2 -2
View File
@@ -280,7 +280,7 @@ void fetch_image_block_fast_ldr(
unsigned int xsize = img.dim_x;
unsigned int ysize = img.dim_y;
unsigned int stride = img.dim_stride;
blk.xpos = xpos;
blk.ypos = ypos;
blk.zpos = zpos;
@@ -300,7 +300,7 @@ void fetch_image_block_fast_ldr(
{
unsigned int xi = astc::min(x, xsize - 1);
vint4 datavi = vint4(plane + (4 * xsize * yi) + (4 * xi));
vint4 datavi = vint4(plane + (4 * stride * yi) + (4 * xi));
vfloat4 datav = int_to_float(datavi) * (65535.0f / 255.0f);
// Compute block metadata
+11 -1
View File
@@ -1351,6 +1351,9 @@ struct avg_args
pixel_region_args arg;
// The above has a reference to the image altread?
/** @brief The image Stride dimensions. */
unsigned int img_size_stride;
/** @brief The image X dimensions. */
unsigned int img_size_x;
@@ -2284,7 +2287,14 @@ void compress_block(
const astcenc_context& ctx,
const image_block& blk,
physical_compressed_block& pcb,
compression_working_buffers& tmpbuf);
#if QUALITY_CONTROL
compression_working_buffers& tmpbuf,
bool calQualityEnable,
int32_t *mseBlock[RGBA_COM]
#else
compression_working_buffers& tmpbuf
#endif
);
/**
* @brief Decompress a symbolic block in to an image block.
View File
View File
View File
View File
+87 -4
View File
@@ -139,6 +139,10 @@ struct compression_workload
uint8_t* data_out;
size_t data_len;
astcenc_error error;
#if QUALITY_CONTROL
bool calQualityEnable;
int32_t *mse[RGBA_COM];
#endif
};
/**
@@ -198,7 +202,11 @@ static void compression_workload_runner(
compression_workload* work = static_cast<compression_workload*>(payload);
astcenc_error error = astcenc_compress_image(
work->context, work->image, &work->swizzle,
work->data_out, work->data_len, thread_id);
work->data_out, work->data_len,
#if QUALITY_CONTROL
work->calQualityEnable, work->mse,
#endif
thread_id);
// This is a racy update, so which error gets returned is a random, but it
// will reliably report an error if an error occurs
@@ -1329,6 +1337,53 @@ static void image_preprocess_premultiply(
}
}
#if QUALITY_CONTROL
constexpr double MAX_PSNR = 99.9;
constexpr double MAX_VALUE = 255;
constexpr double THRESHOLD_R = 30.0;
constexpr double THRESHOLD_G = 30.0;
constexpr double THRESHOLD_B = 30.0;
constexpr double THRESHOLD_A = 30.0;
constexpr double THRESHOLD_RGB = 30.0;
constexpr double LOG_BASE = 10.0;
bool CheckQuality(int32_t* mseIn[RGBA_COM], int blockNum, int blockXYZ)
{
double psnr[RGBA_COM + 1];
double threshold[RGBA_COM + 1] = { THRESHOLD_R, THRESHOLD_G, THRESHOLD_B, THRESHOLD_A, THRESHOLD_RGB};
uint64_t mseTotal[RGBA_COM + 1] = { 0, 0, 0, 0, 0};
for (int i = R_COM; i < RGBA_COM; i++) {
int32_t* mse = mseIn[i];
for (int j = 0; j < blockNum; j++) {
mseTotal[i] += *mse;
if(i != A_COM) mseTotal[RGBA_COM] += *mse;
mse++;
}
}
for (int i = R_COM; i < RGBA_COM; i++) {
if (mseTotal[i] == 0) {
psnr[i] = MAX_PSNR;
continue;
}
double mseRgb = (double)mseTotal[i] / (blockNum * blockXYZ);
psnr[i] = LOG_BASE * log((double)(MAX_VALUE * MAX_VALUE) / mseRgb) / log(LOG_BASE);
}
if (mseTotal[RGBA_COM] == 0) {
psnr[RGBA_COM] = MAX_PSNR;
}
else {
double mseRgb = (double)mseTotal[RGBA_COM] / (blockNum * blockXYZ * (RGBA_COM - 1));
psnr[RGBA_COM] = LOG_BASE * log((double)(MAX_VALUE * MAX_VALUE) / mseRgb) / log(LOG_BASE);
}
printf("astc psnr r%f g%f b%f a%f rgb%f\n",
psnr[R_COM], psnr[G_COM], psnr[B_COM], psnr[A_COM],
psnr[RGBA_COM]);
return (psnr[R_COM] > threshold[R_COM]) && (psnr[G_COM] > threshold[G_COM])
&& (psnr[B_COM] > threshold[B_COM]) && (psnr[A_COM] > threshold[A_COM])
&& (psnr[RGBA_COM] > threshold[RGBA_COM]);
}
#endif
/**
* @brief The main entry point.
*
@@ -1584,12 +1639,25 @@ int main(
compression_workload work;
work.context = codec_context;
image_uncomp_in->dim_stride = image_uncomp_in->dim_x;
work.image = image_uncomp_in;
work.swizzle = cli_config.swz_encode;
work.data_out = buffer;
work.data_len = buffer_size;
work.error = ASTCENC_SUCCESS;
#if QUALITY_CONTROL
work.calQualityEnable = true;
work.mse[R_COM] = work.mse[G_COM] = work.mse[B_COM] = work.mse[A_COM] = nullptr;
if (work.calQualityEnable) {
for (int i = R_COM; i < RGBA_COM; i++) {
work.mse[i] = (int32_t*)calloc(blocks_x * blocks_y, sizeof(int32_t));
if (!work.mse[i]) {
printf("quality control calloc failed");
return -1;
}
}
}
#endif
// Only launch worker threads for multi-threaded use - it makes basic
// single-threaded profiling and debugging a little less convoluted
if (cli_config.thread_count > 1)
@@ -1600,7 +1668,11 @@ int main(
{
work.error = astcenc_compress_image(
work.context, work.image, &work.swizzle,
work.data_out, work.data_len, 0);
work.data_out, work.data_len,
#if QUALITY_CONTROL
work.calQualityEnable, work.mse,
#endif
0);
}
if (work.error != ASTCENC_SUCCESS)
@@ -1608,7 +1680,18 @@ int main(
printf("ERROR: Codec compress failed: %s\n", astcenc_get_error_string(work.error));
return 1;
}
#if QUALITY_CONTROL
if (work.calQualityEnable && !CheckQuality(work.mse, blocks_x * blocks_y, config.block_x * config.block_y)) {
work.error = ASTCENC_ERR_BAD_QUALITY_CHECK;
}
if (work.calQualityEnable) {
for (int i = R_COM; i < RGBA_COM; i++) {
if (work.mse[i]) {
free(work.mse[i]);
}
}
}
#endif
image_comp.block_x = config.block_x;
image_comp.block_y = config.block_y;
image_comp.block_z = config.block_z;