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&#174; 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
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to