[Piglit] [PATCH v4 2/2] arb_shader_precision: add framework for calculating tolerances for complex functions

Micah Fedke micah.fedke at collabora.co.uk
Fri Apr 3 09:45:12 PDT 2015


- update mako templates to support vectors of tolerances
- include manually written tests for a*b+c and fma()

---
 generated_tests/gen_shader_precision_tests.py      | 138 +++++++++++++++++----
 .../templates/gen_shader_precision_tests/fs.mako   |  55 ++++----
 .../templates/gen_shader_precision_tests/gs.mako   |  55 ++++----
 .../templates/gen_shader_precision_tests/vs.mako   |  55 ++++----
 .../fs-fma-float-float-float.shader_test           |  40 ++++++
 .../fs-manual-fma-float-float-float.shader_test    |  40 ++++++
 .../gs-fma-float-float-float.shader_test           |  59 +++++++++
 .../gs-manual-fma-float-float-float.shader_test    |  59 +++++++++
 .../vs-fma-float-float-float.shader_test           |  44 +++++++
 .../vs-manual-fma-float-float-float.shader_test    |  44 +++++++
 10 files changed, 502 insertions(+), 87 deletions(-)
 create mode 100644 tests/spec/arb_shader_precision/fs-fma-float-float-float.shader_test
 create mode 100644 tests/spec/arb_shader_precision/fs-manual-fma-float-float-float.shader_test
 create mode 100644 tests/spec/arb_shader_precision/gs-fma-float-float-float.shader_test
 create mode 100644 tests/spec/arb_shader_precision/gs-manual-fma-float-float-float.shader_test
 create mode 100644 tests/spec/arb_shader_precision/vs-fma-float-float-float.shader_test
 create mode 100644 tests/spec/arb_shader_precision/vs-manual-fma-float-float-float.shader_test

diff --git a/generated_tests/gen_shader_precision_tests.py b/generated_tests/gen_shader_precision_tests.py
index 6c011a3..bef1459 100644
--- a/generated_tests/gen_shader_precision_tests.py
+++ b/generated_tests/gen_shader_precision_tests.py
@@ -25,7 +25,7 @@
 """Generate a set of shader_runner tests for overloaded versions of every
  built-in function specified in arb_shader_precision, based on the test
  vectors computed by builtin_function.py, and structured according to the mako
- templates in shader_precision_templates/.
+ templates in templates/gen_shader_precision_tests.
 
  The vertex, geometry, and fragment shader types are exercised by each test.
  In all cases, the inputs to the built-in functions come from uniforms, so
@@ -43,20 +43,26 @@
  only the largest error value to the tolerance.  This accounts for cases where
  error varies among the elements of a vec or mat result.
 
+ This program updates the tolerance values in the test vectors with tolerances
+ sourced from the GLSL spec (v4.5) and adds a few new tests as well.
+
  This program outputs, to stdout, the name of each file it generates.
 """
 
 from __future__ import print_function, division, absolute_import
 from builtin_function import *
-import os 
+import os
 import numpy
+import struct
 
 import six
 from six.moves import range
 
 from templates import template_file
 
-tolerances = {'pow': 16.0, 
+
+
+tolerances = {'pow': 16.0,
               'exp': 3.0,
               'exp2': 3.0,
               'log': 3.0,
@@ -67,14 +73,87 @@ tolerances = {'pow': 16.0,
               'op-assign-div': 2.5,
               }
 
-trig_builtins = ('sin', 'cos', 'tan', 
-                 'asin', 'acos', 'atan', 
-                 'sinh', 'cosh', 'tanh', 
-                 'asinh', 'acosh', 'atanh')
+shader_precision_spec_fns = ('op-add', 'op-assign-add',
+                             'op-sub', 'op-assign-sub',
+                             'op-mult', 'op-assign-mult',
+                             'op-div', 'op-assign-div',
+                             'degrees', 'radians',
+                             'pow',
+                             'exp',
+                             'exp2',
+                             'log', 'log2',
+                             'sqrt', 'inversesqrt')
 
 def _is_sequence(arg):
     return isinstance(arg, (collections.Sequence, numpy.ndarray))
 
+# The precision for log and log2 from the GLSL spec:
+# 3 ULP outside the range [0.5, 2.0].
+# Absolute error < 2^-21 inside the range [0.5, 2.0].
+def _log_tol(arg):
+    if arg < 0.5 or arg > 2.0:
+        return 3.0
+    elif arg >= 0.5 and arg < 1.0:
+        # in the range [0.5, 1.0), one ulp is 5.960464478e-08,
+        # so 2^-21 is 8 ulps
+        return 8.0
+    else:
+        # in the range [1.0, 2.0), one ulp is 1.192092896e-07,
+        # so 2^-21 is 4 ulps
+        return 4.0
+
+# The precision for exp and exp2 from the GLSL spec:
+# (3 + 2 * |x|) ULP.
+def _exp_tol(arg):
+    return 3.0 + 2.0 * abs(arg)
+
+def _gen_tolerance(name, rettype, args, expected):
+    ret = []
+    compcnt = rettype.num_cols * rettype.num_rows
+
+    for j in range(rettype.num_cols):
+        for i in range(rettype.num_rows):
+            # The precision for add, sub and mult from the GLSL spec:
+            # Correctly rounded.
+            if name in ('op-add', 'op-assign-add', 'op-sub', 'op-assign-sub', 'op-mult', 'op-assign-mult'):
+                ret.append(0.0)
+            # The precision for division from the GLSL spec:
+            # 2.5 ULP for b in the range [2^-126, 2^126].
+            elif name in ('op-div', 'op-assign-div'):
+                divisor = args[1][i] if _is_sequence(args[1]) else args[1]
+                if (divisor >= pow(2,-126) and divisor <= pow(2,126)) or \
+                   (divisor <= -pow(2,-126) and divisor >= -pow(2,126)):
+                    ret.append(2.5)
+                else:
+                    return -1.0
+            # The precision for degrees and radians from the GLSL spec:
+            # Inherited from division
+            # denominator (pi or 180, respectively) is always within [2^-126, 2^126]
+            elif name in ('degrees', 'radians'):
+                ret.append(2.5)
+            # The precision for pow from the GLSL spec:
+            # Inherited from exp2 (x * log2 (y)).
+            elif name is 'pow':
+                x = args[0][i] if _is_sequence(args[0]) else args[0]
+                y = args[1][i] if _is_sequence(args[1]) else args[1]
+                ret.append(_exp_tol(x * _log_tol(y)))
+            elif name in ('exp', 'exp2'):
+                ret.append(_exp_tol(args[j][i] if compcnt > 1 else args[0]))
+            elif name in ('log', 'log2'):
+                ret.append(_log_tol(args[j][i] if compcnt > 1 else args[0]))
+            # The precision for sqrt from the GLSL spec:
+            # Inherited from 1.0 / inversesqrt().
+            elif name is 'sqrt':
+                ret.append(2.5)
+            # The precision for inversesqrt from the GLSL spec:
+            # 2 ULP.
+            elif name is 'inversesqrt':
+                ret.append(2.0)
+            else:
+                return -1.0
+
+    return ret
+
 def make_indexers(signature):
    """Build a list of strings which index into every possible
    value of the result.  For example, if the result is a vec2,
@@ -88,7 +167,7 @@ def make_indexers(signature):
       row_indexers = ['']
    else:
       row_indexers = ['[{0}]'.format(i) for i in range(signature.rettype.num_rows)]
-   return [col_indexer + row_indexer 
+   return [col_indexer + row_indexer
            for col_indexer in col_indexers for row_indexer in row_indexers]
 
 def shader_runner_type(glsl_type):
@@ -116,7 +195,7 @@ def shader_runner_format(values):
         retval = ''
         for x in values:
             assert isinstance(x, (float, np.float32))
-            retval+=' {0:1.8e}'.format(x)
+            retval += ' {0:1.8e}'.format(x)
     else:
         assert isinstance(values, (float, np.float32))
         retval = '{0:1.8e}'.format(values)
@@ -128,34 +207,45 @@ def main():
     """ Main function """
 
     for signature, test_vectors in sorted(six.iteritems(test_suite)):
-        arg_float_check = tuple(
-                        arg.base_type == glsl_float for arg in signature.argtypes)
-        # Filter the test vectors down to only those which deal exclusively in float types
-        #and are not trig functions or determinant()
-        indexers = make_indexers(signature)
-        num_elements = signature.rettype.num_cols*signature.rettype.num_rows
-        invocation = signature.template.format( *['arg{0}'.format(i) 
-                                                for i in range(len(signature.argtypes))])
+        arg_float_check = tuple(arg.base_type == glsl_float for arg in signature.argtypes)
+        arg_mat_check = tuple(arg.is_matrix for arg in signature.argtypes)
+        # Filter the test vectors down to only those which deal exclusively in
+        # non-matrix float types and are specified in the spec
         if (signature.rettype.base_type == glsl_float and
             arg_float_check and
             all(arg_float_check) and
-            signature.name not in trig_builtins and
-            signature.name != 'determinant'): 
+            signature.name in shader_precision_spec_fns and
+            arg_mat_check and
+            (not True in arg_mat_check)):
+            # replace the tolerances in each test_vector with
+            # our own tolerances specified in ulps
+            refined_test_vectors = []
+            complex_tol_type = signature.rettype
+            for test_vector in test_vectors:
+                tolerance = _gen_tolerance(signature.name, signature.rettype, test_vector.arguments, test_vector.result)
+                if tolerance != -1.0:
+                    refined_test_vectors.append(TestVector(test_vector.arguments, test_vector.result, tolerance))
+            # Then generate the shader_test scripts
             for shader_stage in ('vs', 'fs', 'gs'):
                 template = template_file('gen_shader_precision_tests', '{0}.mako'.format(shader_stage))
                 output_filename = os.path.join( 'spec', 'arb_shader_precision',
                                                 '{0}-{1}-{2}.shader_test'.format(
-                                                shader_stage, signature.name, 
-                                                '-'.join(str(argtype) 
+                                                shader_stage, signature.name,
+                                                '-'.join(str(argtype)
                                                 for argtype in signature.argtypes)))
                 print(output_filename)
                 dirname = os.path.dirname(output_filename)
                 if not os.path.exists(dirname):
                     os.makedirs(dirname)
+                indexers = make_indexers(signature)
+                num_elements = signature.rettype.num_cols * signature.rettype.num_rows
+                invocation = signature.template.format( *['arg{0}'.format(i)
+                                                        for i in range(len(signature.argtypes))])
                 with open(output_filename, 'w') as f:
-                    f.write(template.render_unicode( signature=signature, 
-                                                     test_vectors=test_vectors,
-                                                     tolerances=tolerances,
+                    f.write(template.render_unicode( signature=signature,
+                                                     is_complex_tolerance=_is_sequence(tolerance),
+                                                     complex_tol_type=signature.rettype,
+                                                     test_vectors=refined_test_vectors,
                                                      invocation=invocation,
                                                      num_elements=num_elements,
                                                      indexers=indexers,
diff --git a/generated_tests/templates/gen_shader_precision_tests/fs.mako b/generated_tests/templates/gen_shader_precision_tests/fs.mako
index 19ec737..0068642 100644
--- a/generated_tests/templates/gen_shader_precision_tests/fs.mako
+++ b/generated_tests/templates/gen_shader_precision_tests/fs.mako
@@ -19,7 +19,11 @@ void main()
 % for i, arg in enumerate(signature.argtypes):
 uniform ${arg} arg${i};
 % endfor
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${complex_tol_type} tolerance;
+% else:
 uniform float tolerance;
+% endif
 uniform ${signature.rettype} expected;
 
 void main()
@@ -56,29 +60,34 @@ ${' || '.join('(resultbits[{0}]>>31 != expectedbits[{0}]>>31)'.format(i) for i i
   ${signature.rettype} ulps = ${signature.rettype}(\
 ${', '.join('abs(resultbits[{0}] - expectedbits[{0}])'.format(i) for i in range(0, num_elements))}\
 );
-  ##
-  ## find the maximum error in ulps of all the calculations using a nested max() sort
-  ##
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+    ## compare vecs directly, use a boolean version of the rettype
+  b${signature.rettype} calcerr = greaterThan(ulps, tolerance);
+    % else:
+    ##
+    ## find the maximum error in ulps of all the calculations using a nested max() sort
+    ##
   float max_error = \
-    ## start with the outermost max() if there are more than 2 elements
-    ## (two element arrays, eg. vec2, are handled by the final max() below, only)
-    % if num_elements > 2:
+      ## start with the outermost max() if there are more than 2 elements
+      ## (two element arrays, eg. vec2, are handled by the final max() below, only)
+      % if num_elements > 2:
 max( \
-    % endif
-    ## cat each value to compare, with an additional nested max() up until the final two values
-    % for i, indexer in enumerate(indexers[:len(indexers)-2]):
+      % endif
+      ## cat each value to compare, with an additional nested max() up until the final two values
+      % for i, indexer in enumerate(indexers[:len(indexers)-2]):
 ulps${indexer}, \
-    % if i != len(indexers)-3:
+      % if i != len(indexers)-3:
 max(\
-    % endif
-    ## cat the final, deepest, max comparison
-    % endfor
+      % endif
+      ## cat the final, deepest, max comparison
+      % endfor
 max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
-    ## fill in completing parens
-    % for i in range(0, num_elements-2):
+      ## fill in completing parens
+      % for i in range(0, num_elements-2):
 )\
-    % endfor
+      % endfor
 ;
+    %endif
   % else:
     ##
     ## if there is only a single result value generated, compare it directly
@@ -86,18 +95,18 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
   int resultbits = floatBitsToInt(result);
   int expectedbits = floatBitsToInt(expected);
   bool signerr = resultbits>>31 != expectedbits>>31;
-    % if signature.name != 'distance':
-  float ulps = distance(resultbits, expectedbits);
-    % else:
   float ulps = abs(resultbits - expectedbits);
-    % endif
   % endif
   ##
   ## the test passes if there were no sign errors and the ulps are within tolerance
   ##
   gl_FragColor = \
   % if signature.rettype.is_matrix or signature.rettype.is_vector:
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+!signerr && !any(calcerr)\
+    % else:
 !signerr && max_error <= tolerance\
+    % endif
   % else:
 !signerr && ulps <= tolerance\
   % endif
@@ -117,8 +126,12 @@ piglit_vertex/float/2
 uniform ${shader_runner_type(signature.argtypes[i])} arg${i} ${shader_runner_format( column_major_values(test_vector.arguments[i]))}
   % endfor
 uniform ${shader_runner_type(signature.rettype)} expected ${shader_runner_format(column_major_values(test_vector.result))}
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${shader_runner_type(complex_tol_type)} tolerance \
+% else:
 uniform float tolerance \
-${tolerances.get(signature.name, 0.0)}
+% endif
+${shader_runner_format(test_vector.tolerance)}
 draw arrays GL_TRIANGLE_FAN 0 4
 ## shader_runner uses a 250x250 window so we must ensure that test_num <= 250.
 probe rgba ${test_num % 250} 0 0.0 1.0 0.0 1.0
diff --git a/generated_tests/templates/gen_shader_precision_tests/gs.mako b/generated_tests/templates/gen_shader_precision_tests/gs.mako
index de4a3c8..3a76e9b 100644
--- a/generated_tests/templates/gen_shader_precision_tests/gs.mako
+++ b/generated_tests/templates/gen_shader_precision_tests/gs.mako
@@ -24,7 +24,11 @@ flat out vec4 color;
 % for i, arg in enumerate(signature.argtypes):
 uniform ${arg} arg${i};
 % endfor
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${complex_tol_type} tolerance;
+% else:
 uniform float tolerance;
+% endif
 uniform ${signature.rettype} expected;
 
 void main()
@@ -62,29 +66,34 @@ ${' || '.join('(resultbits[{0}]>>31 != expectedbits[{0}]>>31)'.format(i) for i i
   ${signature.rettype} ulps = ${signature.rettype}(\
 ${', '.join('abs(resultbits[{0}] - expectedbits[{0}])'.format(i) for i in range(0, num_elements))}\
 );
-  ##
-  ## find the maximum error in ulps of all the calculations using a nested max() sort
-  ##
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+    ## compare vecs directly, use a boolean version of the rettype
+  b${signature.rettype} calcerr = greaterThan(ulps, tolerance);
+    % else:
+    ##
+    ## find the maximum error in ulps of all the calculations using a nested max() sort
+    ##
   float max_error = \
-    ## start with the outermost max() if there are more than 2 elements
-    ## (two element arrays, eg. vec2, are handled by the final max() below, only)
-    % if num_elements > 2:
+      ## start with the outermost max() if there are more than 2 elements
+      ## (two element arrays, eg. vec2, are handled by the final max() below, only)
+      % if num_elements > 2:
 max( \
-    % endif
-    ## cat each value to compare, with an additional nested max() up until the final two values
-    % for i, indexer in enumerate(indexers[:len(indexers)-2]):
+      % endif
+      ## cat each value to compare, with an additional nested max() up until the final two values
+      % for i, indexer in enumerate(indexers[:len(indexers)-2]):
 ulps${indexer}, \
-    % if i != len(indexers)-3:
+      % if i != len(indexers)-3:
 max(\
-    % endif
-    ## cat the final, deepest, max comparison
-    % endfor
+      % endif
+      ## cat the final, deepest, max comparison
+      % endfor
 max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
-    ## fill in completing parens
-    % for i in range(0, num_elements-2):
+      ## fill in completing parens
+      % for i in range(0, num_elements-2):
 )\
-    % endfor
+      % endfor
 ;
+    %endif
   % else:
     ##
     ## if there is only a single result value generated, compare it directly
@@ -92,18 +101,18 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
   int resultbits = floatBitsToInt(result);
   int expectedbits = floatBitsToInt(expected);
   bool signerr = resultbits>>31 != expectedbits>>31;
-    % if signature.name != 'distance':
-  float ulps = distance(resultbits, expectedbits);
-    % else:
   float ulps = abs(resultbits - expectedbits);
-    % endif
   % endif
   ##
   ## the test passes if there were no sign errors and the ulps are within tolerance
   ##
   tmp_color = \
   % if signature.rettype.is_matrix or signature.rettype.is_vector:
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+!signerr && !any(calcerr)\
+    % else:
 !signerr && max_error <= tolerance\
+    % endif
   % else:
 !signerr && ulps <= tolerance\
   % endif
@@ -136,8 +145,12 @@ piglit_vertex/float/2
 uniform ${shader_runner_type(signature.argtypes[i])} arg${i} ${shader_runner_format( column_major_values(test_vector.arguments[i]))}
   % endfor
 uniform ${shader_runner_type(signature.rettype)} expected ${shader_runner_format(column_major_values(test_vector.result))}
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${shader_runner_type(complex_tol_type)} tolerance \
+% else:
 uniform float tolerance \
-${tolerances.get(signature.name, 0.0)}
+% endif
+${shader_runner_format(test_vector.tolerance)}
 draw arrays GL_TRIANGLE_FAN 0 4
 ## shader_runner uses a 250x250 window so we must ensure that test_num <= 250.
 probe rgba ${test_num % 250} 0 0.0 1.0 0.0 1.0
diff --git a/generated_tests/templates/gen_shader_precision_tests/vs.mako b/generated_tests/templates/gen_shader_precision_tests/vs.mako
index 8d8fad6..d64effd 100644
--- a/generated_tests/templates/gen_shader_precision_tests/vs.mako
+++ b/generated_tests/templates/gen_shader_precision_tests/vs.mako
@@ -14,7 +14,11 @@ flat out vec4 color;
 % for i, arg in enumerate(signature.argtypes):
 uniform ${arg} arg${i};
 % endfor
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${complex_tol_type} tolerance;
+% else:
 uniform float tolerance;
+% endif
 uniform ${signature.rettype} expected;
 
 void main()
@@ -52,29 +56,34 @@ ${' || '.join('(resultbits[{0}]>>31 != expectedbits[{0}]>>31)'.format(i) for i i
   ${signature.rettype} ulps = ${signature.rettype}(\
 ${', '.join('abs(resultbits[{0}] - expectedbits[{0}])'.format(i) for i in range(0, num_elements))}\
 );
-  ##
-  ## find the maximum error in ulps of all the calculations using a nested max() sort
-  ##
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+    ## compare vecs directly, use a boolean version of the rettype
+  b${signature.rettype} calcerr = greaterThan(ulps, tolerance);
+    % else:
+    ##
+    ## find the maximum error in ulps of all the calculations using a nested max() sort
+    ##
   float max_error = \
-    ## start with the outermost max() if there are more than 2 elements
-    ## (two element arrays, eg. vec2, are handled by the final max() below, only)
-    % if num_elements > 2:
+      ## start with the outermost max() if there are more than 2 elements
+      ## (two element arrays, eg. vec2, are handled by the final max() below, only)
+      % if num_elements > 2:
 max( \
-    % endif
-    ## cat each value to compare, with an additional nested max() up until the final two values
-    % for i, indexer in enumerate(indexers[:len(indexers)-2]):
+      % endif
+      ## cat each value to compare, with an additional nested max() up until the final two values
+      % for i, indexer in enumerate(indexers[:len(indexers)-2]):
 ulps${indexer}, \
-    % if i != len(indexers)-3:
+      % if i != len(indexers)-3:
 max(\
-    % endif
-    ## cat the final, deepest, max comparison
-    % endfor
+      % endif
+      ## cat the final, deepest, max comparison
+      % endfor
 max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
-    ## fill in completing parens
-    % for i in range(0, num_elements-2):
+      ## fill in completing parens
+      % for i in range(0, num_elements-2):
 )\
-    % endfor
+      % endfor
 ;
+    %endif
   % else:
     ##
     ## if there is only a single result value generated, compare it directly
@@ -82,18 +91,18 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
   int resultbits = floatBitsToInt(result);
   int expectedbits = floatBitsToInt(expected);
   bool signerr = resultbits>>31 != expectedbits>>31;
-    % if signature.name != 'distance':
-  float ulps = distance(resultbits, expectedbits);
-    % else:
   float ulps = abs(resultbits - expectedbits);
-    % endif
   % endif
   ##
   ## the test passes if there were no sign errors and the ulps are within tolerance
   ##
   color = \
   % if signature.rettype.is_matrix or signature.rettype.is_vector:
+    % if is_complex_tolerance and complex_tol_type.name != 'float':
+!signerr && !any(calcerr)\
+    % else:
 !signerr && max_error <= tolerance\
+    % endif
   % else:
 !signerr && ulps <= tolerance\
   % endif
@@ -121,8 +130,12 @@ piglit_vertex/float/2
 uniform ${shader_runner_type(signature.argtypes[i])} arg${i} ${shader_runner_format( column_major_values(test_vector.arguments[i]))}
   % endfor
 uniform ${shader_runner_type(signature.rettype)} expected ${shader_runner_format(column_major_values(test_vector.result))}
+% if is_complex_tolerance and complex_tol_type.name != 'float':
+uniform ${shader_runner_type(complex_tol_type)} tolerance \
+% else:
 uniform float tolerance \
-${tolerances.get(signature.name, 0.0)}
+% endif
+${shader_runner_format(test_vector.tolerance)}
 draw arrays GL_TRIANGLE_FAN 0 4
 ## shader_runner uses a 250x250 window so we must ensure that test_num <= 250.
 probe rgba ${test_num % 250} 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/fs-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/fs-fma-float-float-float.shader_test
new file mode 100644
index 0000000..3501f46
--- /dev/null
+++ b/tests/spec/arb_shader_precision/fs-fma-float-float-float.shader_test
@@ -0,0 +1,40 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+in vec4 piglit_vertex;
+void main()
+{
+        gl_Position = piglit_vertex;
+}
+
+[fragment shader]
+#extension GL_ARB_shader_precision : require
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  float result = fma(arg0, arg1, arg2);
+  gl_FragColor = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/fs-manual-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/fs-manual-fma-float-float-float.shader_test
new file mode 100644
index 0000000..601f91a
--- /dev/null
+++ b/tests/spec/arb_shader_precision/fs-manual-fma-float-float-float.shader_test
@@ -0,0 +1,40 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+in vec4 piglit_vertex;
+void main()
+{
+        gl_Position = piglit_vertex;
+}
+
+[fragment shader]
+#extension GL_ARB_shader_precision : require
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  float result = arg0 * arg1 + arg2;
+  gl_FragColor = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/gs-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/gs-fma-float-float-float.shader_test
new file mode 100644
index 0000000..7ca5707
--- /dev/null
+++ b/tests/spec/arb_shader_precision/gs-fma-float-float-float.shader_test
@@ -0,0 +1,59 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+in vec4 piglit_vertex;
+flat out vec4 vertex_to_gs;
+void main()
+{
+     vertex_to_gs = piglit_vertex;
+}
+
+[geometry shader]
+#extension GL_ARB_shader_precision : require
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+flat in vec4 vertex_to_gs[3];
+flat out vec4 color;
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  vec4 tmp_color;
+  float result = fma(arg0, arg1, arg2);
+  tmp_color = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+  for (int i = 0; i < 3; i++) {
+    gl_Position = vertex_to_gs[i];
+    color = tmp_color;
+    EmitVertex();
+  }
+}
+
+[fragment shader]
+flat in vec4 color;
+
+void main()
+{
+  gl_FragColor = color;
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/gs-manual-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/gs-manual-fma-float-float-float.shader_test
new file mode 100644
index 0000000..cc35184
--- /dev/null
+++ b/tests/spec/arb_shader_precision/gs-manual-fma-float-float-float.shader_test
@@ -0,0 +1,59 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+in vec4 piglit_vertex;
+flat out vec4 vertex_to_gs;
+void main()
+{
+     vertex_to_gs = piglit_vertex;
+}
+
+[geometry shader]
+#extension GL_ARB_shader_precision : require
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+flat in vec4 vertex_to_gs[3];
+flat out vec4 color;
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  vec4 tmp_color;
+  float result = arg0 * arg1 + arg2;
+  tmp_color = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+  for (int i = 0; i < 3; i++) {
+    gl_Position = vertex_to_gs[i];
+    color = tmp_color;
+    EmitVertex();
+  }
+}
+
+[fragment shader]
+flat in vec4 color;
+
+void main()
+{
+  gl_FragColor = color;
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/vs-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/vs-fma-float-float-float.shader_test
new file mode 100644
index 0000000..64dcbb9
--- /dev/null
+++ b/tests/spec/arb_shader_precision/vs-fma-float-float-float.shader_test
@@ -0,0 +1,44 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+#extension GL_ARB_shader_precision : require
+in vec4 piglit_vertex;
+flat out vec4 color;
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  gl_Position = piglit_vertex;
+  float result = fma(arg0, arg1, arg2);
+  color = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[fragment shader]
+flat in vec4 color;
+
+void main()
+{
+  gl_FragColor = color;
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_shader_precision/vs-manual-fma-float-float-float.shader_test b/tests/spec/arb_shader_precision/vs-manual-fma-float-float-float.shader_test
new file mode 100644
index 0000000..dcbe508
--- /dev/null
+++ b/tests/spec/arb_shader_precision/vs-manual-fma-float-float-float.shader_test
@@ -0,0 +1,44 @@
+
+[require]
+GLSL >= 4.00
+
+[vertex shader]
+#extension GL_ARB_shader_precision : require
+in vec4 piglit_vertex;
+flat out vec4 color;
+uniform float arg0;
+uniform float arg1;
+uniform float arg2;
+uniform float expected_a;
+uniform float expected_b;
+
+void main()
+{
+  gl_Position = piglit_vertex;
+  float result = arg0 * arg1 + arg2;
+  color = result == expected_a || result == expected_b ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[fragment shader]
+flat in vec4 color;
+
+void main()
+{
+  gl_FragColor = color;
+}
+
+[vertex data]
+piglit_vertex/float/2
+-1.0 -1.0
+ 1.0 -1.0
+ 1.0  1.0
+-1.0  1.0
+
+[test]
+uniform float arg0  -2.99999993e-02
+uniform float arg1  -8.50000024e-01
+uniform float arg2  -2.54999995e-02
+uniform float expected_a  0.00000000e+00
+uniform float expected_b  6.22123464e-10
+draw arrays GL_TRIANGLE_FAN 0 4
+probe rgba 0 0 0.0 1.0 0.0 1.0
-- 
2.3.5



More information about the Piglit mailing list