Collect the maximum error for fetch/unpack tests, and ratio of flipped
to total bits for pack tests.
Add lenient thresholds for S3TC tests.
---
progs/gallium/unit/u_format_test.c | 163 +++++++++++++++++++-----------------
1 files changed, 86 insertions(+), 77 deletions(-)
diff --git a/progs/gallium/unit/u_format_test.c
b/progs/gallium/unit/u_format_test.c
index 53e0284..1911dad 100644
--- a/progs/gallium/unit/u_format_test.c
+++ b/progs/gallium/unit/u_format_test.c
@@ -36,22 +36,48 @@
#include "util/u_format_s3tc.h"
+static float
+float_error(float x, float y)
+{
+ return fabsf(y - x);
+}
+
+static float
+byte_error(uint8_t x, uint8_t y)
+{
+ return float_error(x / 255.0, y / 255.0);
+}
+
+/* this is done in this terrible way only because these are unit tests.
+ * a real implementation must use a lookup table, or the mask/shift/add
+ * algorithm in the Linux source
+ * it should also use the builtin/intrinsic if available
+ */
+static unsigned
+popcnt8(uint8_t v)
+{
+ unsigned i;
+ unsigned cnt = 0;
+ for(i = 0; i < 8; ++i)
+ cnt += ((v >> i) & 1);
+ return cnt;
+}
+
static boolean
-compare_float(float x, float y)
+print_max_error(const struct util_format_description *format_desc, float
max_error)
{
- float error = y - x;
+ if(max_error <= FLT_EPSILON)
+ return TRUE;
- if (error < 0.0f)
- error = -error;
+ printf("MAX ABS ERROR: %f float, %.1f 8scaled\n", max_error, max_error *
255.0);
- if (error > FLT_EPSILON) {
- return FALSE;
- }
+ /* compression tests aren't currently perfect, so be lenient here */
+ if(format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC && max_error < 0.01f)
+ return TRUE;
- return TRUE;
+ return FALSE;
}
-
static void
print_packed(const struct util_format_description *format_desc,
const char *prefix,
@@ -69,6 +95,31 @@ print_packed(const struct util_format_description
*format_desc,
printf("%s", suffix);
}
+static boolean
+print_packed_results(const struct util_format_description *format_desc, const
struct util_format_test_case *test, uint8_t* packed)
+{
+ unsigned flipped_bits = 0;
+ unsigned total_bits = 0;
+ float flipped_bits_ratio;
+ unsigned i;
+ for (i = 0; i < format_desc->block.bits/8; ++i) {
+ flipped_bits += popcnt8((test->packed[i] ^ packed[i]) & test->mask[i]);
+ total_bits += popcnt8(test->mask[i]);
+ }
+
+ flipped_bits_ratio = (float)flipped_bits / total_bits;
+
+ if (flipped_bits)
+ printf("FLIPPED BITS: %u (%u %%)\n", flipped_bits,
(unsigned)(flipped_bits_ratio * 100.0));
+
+ /* TODO: S3TC threshold is random */
+ if (flipped_bits_ratio > (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC ?
0.1 : 0)) {
+ print_packed(format_desc, "FAILED: ", packed, " obtained\n");
+ print_packed(format_desc, " ", test->packed, " expected\n");
+ return FALSE;
+ }
+ return TRUE;
+}
static void
print_unpacked_doubl(const struct util_format_description *format_desc,
@@ -94,7 +145,7 @@ print_unpacked_doubl(const struct util_format_description
*format_desc,
static void
print_unpacked_float(const struct util_format_description *format_desc,
const char *prefix,
- const float
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
+ float
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
const char *suffix)
{
unsigned i, j;
@@ -115,7 +166,7 @@ print_unpacked_float(const struct util_format_description
*format_desc,
static void
print_unpacked_8unorm(const struct util_format_description *format_desc,
const char *prefix,
- const uint8_t
unpacked[][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
+ uint8_t unpacked[][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
const char *suffix)
{
unsigned i, j;
@@ -138,26 +189,23 @@ test_format_fetch_float(const struct
util_format_description *format_desc,
{
float
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] =
{ { { 0 } } };
unsigned i, j, k;
- boolean success;
+ float max_error = 0.0f;
- success = TRUE;
for (i = 0; i < format_desc->block.height; ++i) {
for (j = 0; j < format_desc->block.width; ++j) {
format_desc->fetch_float(unpacked[i][j], test->packed, j, i);
- for (k = 0; k < 4; ++k) {
- if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
- success = FALSE;
- }
- }
+ for (k = 0; k < 4; ++k)
+ max_error = MAX2(max_error, float_error(test->unpacked[i][j][k],
unpacked[i][j][k]));
}
}
- if (!success) {
+ if (!print_max_error(format_desc, max_error)) {
print_unpacked_float(format_desc, "FAILED: ", unpacked, " obtained\n");
print_unpacked_doubl(format_desc, " ", test->unpacked, "
expected\n");
+ return FALSE;
}
- return success;
+ return TRUE;
}
@@ -167,27 +215,24 @@ test_format_unpack_float(const struct
util_format_description *format_desc,
{
float
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] =
{ { { 0 } } };
unsigned i, j, k;
- boolean success;
+ float max_error = 0.0f;
format_desc->unpack_float(&unpacked[0][0][0], sizeof unpacked[0],
test->packed, 0, format_desc->block.width, format_desc->block.height);
- success = TRUE;
for (i = 0; i < format_desc->block.height; ++i) {
for (j = 0; j < format_desc->block.width; ++j) {
- for (k = 0; k < 4; ++k) {
- if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
- success = FALSE;
- }
- }
+ for (k = 0; k < 4; ++k)
+ max_error = MAX2(max_error, float_error(test->unpacked[i][j][k],
unpacked[i][j][k]));
}
}
- if (!success) {
+ if (!print_max_error(format_desc, max_error)) {
print_unpacked_float(format_desc, "FAILED: ", unpacked, " obtained\n");
print_unpacked_doubl(format_desc, " ", test->unpacked, "
expected\n");
+ return FALSE;
}
- return success;
+ return TRUE;
}
@@ -199,16 +244,10 @@ test_format_pack_float(const struct
util_format_description *format_desc,
float
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
unsigned i, j, k;
- boolean success;
- if (test->format == PIPE_FORMAT_DXT1_RGBA) {
- /*
- * Skip S3TC as packed representation is not canonical.
- *
- * TODO: Do a round trip conversion.
- */
+ /* XXX: this test is broken */
+ if (test->format == PIPE_FORMAT_DXT1_RGBA)
return TRUE;
- }
memset(packed, 0, sizeof packed);
for (i = 0; i < format_desc->block.height; ++i) {
@@ -221,17 +260,7 @@ test_format_pack_float(const struct
util_format_description *format_desc,
format_desc->pack_float(packed, 0, &unpacked[0][0][0], sizeof unpacked[0],
format_desc->block.width, format_desc->block.height);
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
+ return print_packed_results(format_desc, test, packed);
}
@@ -266,29 +295,26 @@ test_format_unpack_8unorm(const struct
util_format_description *format_desc,
uint8_t
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] =
{ { { 0 } } };
uint8_t
expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] =
{ { { 0 } } };
unsigned i, j, k;
- boolean success;
+ float max_error;
format_desc->unpack_8unorm(&unpacked[0][0][0], sizeof unpacked[0],
test->packed, 0, 1, 1);
convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]);
- success = TRUE;
for (i = 0; i < format_desc->block.height; ++i) {
for (j = 0; j < format_desc->block.width; ++j) {
- for (k = 0; k < 4; ++k) {
- if (expected[i][j][k] != unpacked[i][j][k]) {
- success = FALSE;
- }
- }
+ for (k = 0; k < 4; ++k)
+ max_error = MAX2(max_error, byte_error(expected[i][j][k],
unpacked[i][j][k]));
}
}
- if (!success) {
+ if (!print_max_error(format_desc, max_error)) {
print_unpacked_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
print_unpacked_8unorm(format_desc, " ", expected, " expected\n");
+ return FALSE;
}
- return success;
+ return TRUE;
}
@@ -298,17 +324,10 @@ test_format_pack_8unorm(const struct
util_format_description *format_desc,
{
uint8_t
unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i;
- boolean success;
- if (test->format == PIPE_FORMAT_DXT1_RGBA) {
- /*
- * Skip S3TC as packed representation is not canonical.
- *
- * TODO: Do a round trip conversion.
- */
+ /* XXX: this test is broken */
+ if (test->format == PIPE_FORMAT_DXT1_RGBA)
return TRUE;
- }
if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0]))
{
/*
@@ -321,17 +340,7 @@ test_format_pack_8unorm(const struct
util_format_description *format_desc,
format_desc->pack_8unorm(packed, 0, &unpacked[0][0][0], sizeof unpacked[0],
1, 1);
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
+ return print_packed_results(format_desc, test, packed);
}
--
1.7.0.1.147.g6d84b
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev