[Piglit] [PATCH 1/2] ARB_shading_language_packing: Allow some imprecision in unpackUnorm4x8

Matt Turner mattst88 at gmail.com
Thu Jan 31 22:51:15 PST 2013


The unpack builtins are implemented using floating-point division, which
is implemented by reciprocal+multiply. As it so happens, 1.0/255.0 falls
almost exactly between two representable 32-bit floats and leads to bad
rounding. None of the other divisors (127, 32767, 65535) have this
property.

So allow the result of unpackUnorm4x8 to be within some small epsilon
(0.00001) of the actual value. Some values like 0.0 and 1.0 should be
calculated exactly, so handle them specially.
---
 generated_tests/gen_builtin_packing_tests.py | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/generated_tests/gen_builtin_packing_tests.py b/generated_tests/gen_builtin_packing_tests.py
index 7c1074e..0f7510f 100644
--- a/generated_tests/gen_builtin_packing_tests.py
+++ b/generated_tests/gen_builtin_packing_tests.py
@@ -231,6 +231,8 @@ vs_unpack_template = Template(dedent("""\
 
     uniform highp uint func_input;
 
+    uniform bool exact;
+
     % for j in range(func.num_valid_outputs):
     uniform ${func.result_precision} ${func.vector_type} expect${j};
     % endfor
@@ -246,6 +248,9 @@ vs_unpack_template = Template(dedent("""\
 
         if (false
             % for j in range(func.num_valid_outputs):
+            % if not func.exact:
+            || (!exact && distance(actual, expect${j}) < 0.00001)
+            %endif
             || actual == expect${j}
             % endfor
            ) {
@@ -274,6 +279,9 @@ vs_unpack_template = Template(dedent("""\
     [test]
     % for io in func.inout_seq:
     uniform uint func_input ${io.input}
+    % if not func.exact:
+    uniform int exact ${int(int(io.input[:-1]) in (0x0, 0xffffffff))}
+    % endif
     % for j in range(func.num_valid_outputs):
     uniform ${func.vector_type} expect${j} ${" ".join(io.valid_outputs[j])}
     % endfor
@@ -370,6 +378,8 @@ fs_unpack_template = Template(dedent("""\
 
     uniform highp uint func_input;
 
+    uniform bool exact;
+
     % for i in range(func.num_valid_outputs):
     uniform ${func.result_precision} ${func.vector_type} expect${i};
     % endfor
@@ -382,6 +392,9 @@ fs_unpack_template = Template(dedent("""\
 
         if (false
             % for i in range(func.num_valid_outputs):
+            % if not func.exact:
+            || (!exact && distance(actual, expect${i}) < 0.00001)
+            %endif
             || actual == expect${i}
             % endfor
            ) {
@@ -401,6 +414,9 @@ fs_unpack_template = Template(dedent("""\
     [test]
     % for io in func.inout_seq:
     uniform uint func_input ${io.input}
+    % if not func.exact:
+    uniform int exact ${int(int(io.input[:-1]) in (0x0, 0xffffffff))}:
+    % endif
     % for i in range(func.num_valid_outputs):
     uniform ${func.vector_type} expect${i} ${" ".join(io.valid_outputs[i])}
     % endfor
@@ -1271,6 +1287,9 @@ class FuncInfo:
 
     - requirements: A set of API/extension requirments to be listed in the
       .shader_test's [requires] section.
+
+    - exact: Whether the generated results must be exact (e.g., 0.0 and 1.0
+      should always be converted exactly).
     """
 
     def __init__(self, name, requirements):
@@ -1279,6 +1298,7 @@ class FuncInfo:
         self.inout_seq = inout_table[name]
         self.num_valid_outputs = len(self.inout_seq[0].valid_outputs)
         self.requirements = requirements
+        self.exact = not name.endswith("unpackUnorm4x8")
 
         if name.endswith("2x16"):
             self.dimension = "2x16"
-- 
1.7.12.4



More information about the Piglit mailing list