<div dir="ltr">On 31 January 2013 22:51, Matt Turner <span dir="ltr"><<a href="mailto:mattst88@gmail.com" target="_blank">mattst88@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
The unpack builtins are implemented using floating-point division, which<br>
is implemented by reciprocal+multiply.</blockquote><div><br></div><div>This should probably say something like "Which is implemented by reciprocal+multiply on Mesa/i965".  Other drivers don't necessarily use reciprocal+multiply to do division.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> As it so happens, 1.0/255.0 falls<br>
almost exactly between two representable 32-bit floats and leads to bad<br>
rounding. None of the other divisors (127, 32767, 65535) have this<br>
property. <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
So allow the result of unpackUnorm4x8 to be within some small epsilon<br>
(0.00001) of the actual value. Some values like 0.0 and 1.0 should be<br>
calculated exactly, so handle them specially.<br>
---<br>
 generated_tests/gen_builtin_packing_tests.py | 20 ++++++++++++++++++++<br>
 1 file changed, 20 insertions(+)<br>
<br>
diff --git a/generated_tests/gen_builtin_packing_tests.py b/generated_tests/gen_builtin_packing_tests.py<br>
index 7c1074e..0f7510f 100644<br>
--- a/generated_tests/gen_builtin_packing_tests.py<br>
+++ b/generated_tests/gen_builtin_packing_tests.py<br>
@@ -231,6 +231,8 @@ vs_unpack_template = Template(dedent("""\<br>
<br>
     uniform highp uint func_input;<br>
<br>
+    uniform bool exact;<br>
+<br>
     % for j in range(func.num_valid_outputs):<br>
     uniform ${func.result_precision} ${func.vector_type} expect${j};<br>
     % endfor<br>
@@ -246,6 +248,9 @@ vs_unpack_template = Template(dedent("""\<br>
<br>
         if (false<br>
             % for j in range(func.num_valid_outputs):<br>
+            % if not func.exact:<br>
+            || (!exact && distance(actual, expect${j}) < 0.00001)<br>
+            %endif<br>
             || actual == expect${j}<br>
             % endfor<br></blockquote><div><br></div><div>I had a little trouble following the boolean logic here.  Would something like this be clearer?<br><br></div><div>% for j in range(func.num_valid_outputs):<br>|| (exact ? actual == expect${j}<br>
          : distance(actual, expect${j}) < 0.00001)<br>% endfor<br><br></div><div>(I don't consider it a blocking issue, though.  The code you've written is correct, it just took me a while to puzzle out.)<br></div>
<div><br>Note: since my suggested change would cause the shader to always reference the "exact" uniform, you'd have to change the code below to emit "uniform" commands even when func.exact is true.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            ) {<br>
@@ -274,6 +279,9 @@ vs_unpack_template = Template(dedent("""\<br>
     [test]<br>
     % for io in func.inout_seq:<br>
     uniform uint func_input ${io.input}<br>
+    % if not func.exact:<br>
+    uniform int exact ${int(int(io.input[:-1]) in (0x0, 0xffffffff))}<br>
+    % endif<br>
     % for j in range(func.num_valid_outputs):<br>
     uniform ${func.vector_type} expect${j} ${" ".join(io.valid_outputs[j])}<br>
     % endfor<br>
@@ -370,6 +378,8 @@ fs_unpack_template = Template(dedent("""\<br>
<br>
     uniform highp uint func_input;<br>
<br>
+    uniform bool exact;<br>
+<br>
     % for i in range(func.num_valid_outputs):<br>
     uniform ${func.result_precision} ${func.vector_type} expect${i};<br>
     % endfor<br>
@@ -382,6 +392,9 @@ fs_unpack_template = Template(dedent("""\<br>
<br>
         if (false<br>
             % for i in range(func.num_valid_outputs):<br>
+            % if not func.exact:<br>
+            || (!exact && distance(actual, expect${i}) < 0.00001)<br>
+            %endif<br>
             || actual == expect${i}<br>
             % endfor<br>
            ) {<br>
@@ -401,6 +414,9 @@ fs_unpack_template = Template(dedent("""\<br>
     [test]<br>
     % for io in func.inout_seq:<br>
     uniform uint func_input ${io.input}<br>
+    % if not func.exact:<br>
+    uniform int exact ${int(int(io.input[:-1]) in (0x0, 0xffffffff))}:<br>
+    % endif<br>
     % for i in range(func.num_valid_outputs):<br>
     uniform ${func.vector_type} expect${i} ${" ".join(io.valid_outputs[i])}<br>
     % endfor<br>
@@ -1271,6 +1287,9 @@ class FuncInfo:<br>
<br>
     - requirements: A set of API/extension requirments to be listed in the<br>
       .shader_test's [requires] section.<br>
+<br>
+    - exact: Whether the generated results must be exact (e.g., 0.0 and 1.0<br>
+      should always be converted exactly).<br>
     """<br>
<br>
     def __init__(self, name, requirements):<br>
@@ -1279,6 +1298,7 @@ class FuncInfo:<br>
         self.inout_seq = inout_table[name]<br>
         self.num_valid_outputs = len(self.inout_seq[0].valid_outputs)<br>
         self.requirements = requirements<br>
+        self.exact = not name.endswith("unpackUnorm4x8")<br></blockquote><div><br></div><div>I'm not comfortable with only applying this change to unpackUnorm4x8.  Although we've only seen the failure in unpackUnorm4x8, the reason for that is highly specific to Mesa/i965.  Other implementations might conceivably have different sources of rounding errors, and IMHO we shouldn't make an exception that's so specific to i965.<br>
<br>I believe the only unpack function we should require to be exact is unpackHalf2x16.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
         if name.endswith("2x16"):<br>
             self.dimension = "2x16"<br>
<span class=""><font color="#888888">--<br>
1.7.12.4<br>
<br>
_______________________________________________<br>
Piglit mailing list<br>
<a href="mailto:Piglit@lists.freedesktop.org">Piglit@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br></font></span></blockquote><div><br></div><br></div></div></div>