[Piglit] [PATCH 3/3] arb_shader_precision: enable calculation of complex function tolerances
Micah Fedke
micah.fedke at collabora.co.uk
Tue Feb 24 15:49:15 PST 2015
- update mako templates to support vectors of tolerances
---
generated_tests/gen_shader_precision_tests.py | 23 +++++++---
.../templates/gen_shader_precision_tests/fs.mako | 51 ++++++++++++++--------
.../templates/gen_shader_precision_tests/gs.mako | 51 ++++++++++++++--------
.../templates/gen_shader_precision_tests/vs.mako | 51 ++++++++++++++--------
4 files changed, 119 insertions(+), 57 deletions(-)
diff --git a/generated_tests/gen_shader_precision_tests.py b/generated_tests/gen_shader_precision_tests.py
index 3492c87..2586346 100644
--- a/generated_tests/gen_shader_precision_tests.py
+++ b/generated_tests/gen_shader_precision_tests.py
@@ -463,15 +463,21 @@ def main():
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))])
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'):
+ # replace the tolerances in each test_vector with
+ # our own tolerances specified in ulps and
+ # reject vectors that produce results with too much error
+ refined_test_vectors = []
+ complex_tol_type = signature.rettype
+ for test_num, test_vector in enumerate(test_vectors):
+ tolerance = _gen_tolerance(signature.name, signature.rettype, test_vector.arguments)
+ 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',
@@ -483,10 +489,15 @@ def main():
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=simple_fns,
+ is_complex_tolerance=signature.name in complex_fns,
+ 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..89829e7 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
@@ -97,7 +106,11 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
##
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 +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/generated_tests/templates/gen_shader_precision_tests/gs.mako b/generated_tests/templates/gen_shader_precision_tests/gs.mako
index de4a3c8..5174efb 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
@@ -103,7 +112,11 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
##
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 +149,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..367d3a2 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
@@ -93,7 +102,11 @@ max(ulps${indexers[len(indexers)-2]}, ulps${indexers[len(indexers)-1]})\
##
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 +134,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
--
2.2.2
More information about the Piglit
mailing list