[Piglit] [PATCH RFC v2] arb_shader_precision: add tests for floating point precision
Dylan Baker
baker.dylan.c at gmail.com
Fri Nov 7 15:20:05 PST 2014
I strongly object to adding another generator that does crazy string
concatenation to create tests. These are incredibly hard to read,
understand, and modify. We have a mako dependency for this purpose.
Please use mako instead.
Dylan
On Friday, November 07, 2014 05:01:41 PM Micah Fedke wrote:
> This generated_tests script creates a suite of tests that measure the
> floating point precision of most GLSL built-ins, according to
> ARB_shader_precision. Test vectors come from builtin_function.py, but
> are filtered down to avoid non-float types.
>
> These tests are reporting precision errors in ceil, cross, mod,
> op-assign-div, op-assign-mult, div, mult, reflect and refract on
> Ivybridge.
> ---
>
> Updates since the first RFC:
> Moved tests from tests/spec/ to generated_tests/ for much less NIH. The
> generator script creates fs, vs, gs and cs tests for all vectors that deal in
> floats (eg. op-add-float-float but not op-add-ivec3-int). Trig functions and
> determinant() are excluded, as these do not have a required precision per
> ARB_shader_precision.
>
> I am concerned that the test vectors provided by builtin_function.py don't
> probe the limits of the floating point format sufficiently, as floating point
> error varies across the range of available floats, but this should be enough
> for a first swing.
>
> Note: I am new to the project and don't have commit access.
>
> generated_tests/CMakeLists.txt | 5 +
> generated_tests/gen_shader_precision_tests.py | 610 ++++++++++++++++++++++++++
> tests/all.py | 19 +
> 3 files changed, 634 insertions(+)
> create mode 100644 generated_tests/gen_shader_precision_tests.py
>
> diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt
> index 6d27b3e..ee381ac 100644
> --- a/generated_tests/CMakeLists.txt
> +++ b/generated_tests/CMakeLists.txt
> @@ -31,6 +31,10 @@ piglit_make_generated_tests(
> gen_constant_array_size_tests.py
> builtin_function.py)
> piglit_make_generated_tests(
> + shader_precision_tests.list
> + gen_shader_precision_tests.py
> + builtin_function.py)
> +piglit_make_generated_tests(
> const_builtin_equal_tests.list
> gen_const_builtin_equal_tests.py)
> piglit_make_generated_tests(
> @@ -100,6 +104,7 @@ add_custom_target(gen-tests ALL
> outerproduct_invalid_params.list
> builtin_uniform_tests.list
> constant_array_size_tests.list
> + shader_precision_tests.list
> const_builtin_equal_tests.list
> builtin_cl_int_tests.list
> builtin_cl_math_tests.list
> diff --git a/generated_tests/gen_shader_precision_tests.py b/generated_tests/gen_shader_precision_tests.py
> new file mode 100644
> index 0000000..3f091a8
> --- /dev/null
> +++ b/generated_tests/gen_shader_precision_tests.py
> @@ -0,0 +1,610 @@
> +# coding=utf-8
> +#
> +# Copyright © 2011 Intel Corporation
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a
> +# copy of this software and associated documentation files (the "Software"),
> +# to deal in the Software without restriction, including without limitation
> +# the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +# and/or sell copies of the Software, and to permit persons to whom the
> +# Software is furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice (including the next
> +# paragraph) shall be included in all copies or substantial portions of the
> +# Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> +# DEALINGS IN THE SOFTWARE.
> +
> +# Generate a set of shader_runner tests for every overloaded version
> +# of every built-in function, based on the test vectors computed by
> +# builtin_function.py.
> +#
> +# In each set of generated tests, one test exercises the built-in
> +# function in each type of shader (vertex, geometry, and fragment).
> +# In all cases, the inputs to the built-in function come from
> +# uniforms, so that the effectiveness of the test won't be
> +# circumvented by constant folding in the GLSL compiler.
> +#
> +# The tests operate by invoking the built-in function in the
> +# appropriate shader, applying a scale and offset so that the expected
> +# values are in the range [0.25, 0.75], and then outputting the result
> +# as a solid rgba color, which is then checked using shader_runner's
> +# "probe rgba" command.
> +#
> +# For built-in functions whose result type is a matrix, the test
> +# checks one column at a time.
> +#
> +# This program outputs, to stdout, the name of each file it generates.
> +# With the optional argument --names-only, it only outputs the names
> +# of the files; it doesn't generate them.
> +
> +from builtin_function import *
> +import abc
> +import numpy
> +import optparse
> +import os
> +import os.path
> +import sys
> +
> +
> +def shader_runner_format(values):
> + """Format the given values for use in a shader_runner "uniform" or
> + "probe rgba" command. Bools are converted to 0's and 1's, and
> + values are separated by spaces.
> + """
> + transformed_values = []
> + for value in values:
> + if isinstance(value, (bool, np.bool_)):
> + transformed_values.append(int(value))
> + else:
> + transformed_values.append(value)
> + return ' '.join(repr(x) for x in transformed_values)
> +
> +
> +def shader_runner_type(glsl_type):
> + """Return the appropriate type name necessary for binding a
> + uniform of the given type using shader_runner's "uniform" command.
> + Boolean values and vectors are converted to ints, and square
> + matrices are written in "matNxN" form.
> + """
> + if glsl_type.base_type == glsl_bool:
> + if glsl_type.is_scalar:
> + return 'int'
> + else:
> + return 'ivec{0}'.format(glsl_type.num_rows)
> + elif glsl_type.is_matrix:
> + return 'mat{0}x{1}'.format(glsl_type.num_cols, glsl_type.num_rows)
> + else:
> + return str(glsl_type)
> +
> +
> +class Comparator(object):
> + """Base class which abstracts how we compare expected and actual
> + values.
> + """
> + __metaclass__ = abc.ABCMeta
> +
> + def make_additional_declarations(self):
> + """Return additional declarations, if any, that are needed in
> + the shader program.
> + """
> + return ''
> +
> + @abc.abstractmethod
> + def make_result_handler(self, invocation, output_var):
> + """Return the shader code that is needed to produce the result
> + and store it in output_var.
> +
> + invocation is the GLSL code to compute the output of the
> + built-in function.
> + """
> +
> + @abc.abstractmethod
> + def make_result_test(self, test_num, test_vector):
> + """Return the shader_runner test code that is needed to test a
> + single test vector.
> + """
> +
> + def testname_suffix(self):
> + """Return a string to be used as a suffix on the test name to
> + distinguish it from tests using other comparators."""
> + return ''
> +
> +
> +class FloatComparator(Comparator):
> + """Comparator that tests functions returning floats or vecs using a
> + strict equality test.
> +
> + This comparator causes code to be generated in the following form:
> +
> + rettype result = func(args);
> + output_var = distance(result, expected) <= tolerance
> + ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
> + """
> + def __init__(self, signature):
> + self.__signature = signature
> +
> + def make_additional_declarations(self):
> + decls = 'uniform float tolerance;\n'
> + decls += 'uniform {0} expected;\n'.format(self.__signature.rettype)
> + return decls
> +
> + def make_indexers(self):
> + """Build a list of strings which index into every possible
> + value of the result. For example, if the result is a vec2,
> + then build the indexers ['[0]', '[1]'].
> + """
> + if self.__signature.rettype.num_cols == 1:
> + col_indexers = ['']
> + else:
> + col_indexers = ['[{0}]'.format(i)
> + for i in xrange(self.__signature.rettype.num_cols)]
> + if self.__signature.rettype.num_rows == 1:
> + row_indexers = ['']
> + else:
> + row_indexers = ['[{0}]'.format(i)
> + for i in xrange(self.__signature.rettype.num_rows)]
> + return [col_indexer + row_indexer
> + for col_indexer in col_indexers
> + for row_indexer in row_indexers]
> +
> + def make_result_handler(self, invocation, output_var):
> + statements = ' {0} result = {1};\n'.format(
> + self.__signature.rettype, invocation)
> + # need special handling when testing distance or when the rettype
> + # is a matrix or vector
> + if self.__signature.name == 'distance' or \
> + self.__signature.rettype.is_matrix or self.__signature.rettype.is_vector:
> + statements += ' int resultbits[{0}] = int[{0}]({1});\n'.format(
> + self.__signature.rettype.num_cols*self.__signature.rettype.num_rows, ', '.join(
> + 'floatBitsToInt(result{0})'.format(indexer) for indexer in self.make_indexers()))
> + statements += ' int expectedbits[{0}] = int[{0}]({1});\n'.format(
> + self.__signature.rettype.num_cols*self.__signature.rettype.num_rows, ', '.join(
> + 'floatBitsToInt(expected{0})'.format(indexer) for indexer in self.make_indexers()))
> + statements += ' bool signerr = {0};\n'.format(
> + ' || '.join(('(resultbits[{0}]>>31 != expectedbits[{0}]>>31)'.format(index)
> + for index in range(0, self.__signature.rettype.num_cols*self.__signature.rettype.num_rows))))
> + # use the equivalent length(p0-p1) when testing distance()
> + if self.__signature.name == 'distance':
> + statements += ' {0} ulps = {0}({1});\n'.format(
> + self.__signature.rettype, ', '.join(
> + 'length(resultbits[{0}] - expectedbits[{0}])'.format(index)
> + for index in range(0, self.__signature.rettype.num_cols*self.__signature.rettype.num_rows)))
> + else:
> + statements += ' {0} ulps = {0}({1});\n'.format(
> + self.__signature.rettype, ', '.join(
> + 'distance(resultbits[{0}],expectedbits[{0}])'.format(index)
> + for index in range(0, self.__signature.rettype.num_cols*self.__signature.rettype.num_rows)))
> + indexers = self.make_indexers()
> + statements += ' float max_error = {0}{1}{2}{3};\n'.format(
> + 'max( ' if self.__signature.rettype.num_cols*self.__signature.rettype.num_rows > 2 else '',
> + 'max('.join(
> + 'ulps{0}, '.format(indexer)
> + for indexer in indexers[:len(indexers)-2]),
> + 'max(ulps{0}, ulps{1})'.format(indexers[len(indexers)-2], indexers[len(indexers)-1]),
> + ''.join(')'.format(index) for index in range(0, self.__signature.rettype.num_cols*self.__signature.rettype.num_rows-2)))
> + condition = '!signerr && max_error <= tolerance'
> + else:
> + statements += ' int resultbits = floatBitsToInt(result);\n'
> + statements += ' int expectedbits = floatBitsToInt(expected);\n'
> + statements += ' bool signerr = resultbits>>31 != expectedbits>>31;\n'
> + statements += ' float ulps = distance(resultbits, expectedbits);\n'
> + condition = '!signerr && ulps <= tolerance'
> + statements += ' {v} = {cond} ? {green} : {red};\n'.format(
> + v=output_var, cond=condition, green='vec4(0.0, 1.0, 0.0, 1.0)',
> + red='vec4(1.0, 0.0, 0.0, 1.0)')
> + return statements
> +
> + def make_result_test(self, test_num, test_vector, draw):
> + test = 'uniform {0} expected {1}\n'.format(
> + shader_runner_type(self.__signature.rettype),
> + shader_runner_format(column_major_values(test_vector.result)))
> + override_tolerances = {'pow': 16.0,
> + 'exp': 3.0,
> + 'exp2': 3.0,
> + 'log': 3.0,
> + 'log2': 3.0,
> + 'sqrt': 3.0,
> + 'inversesqrt': 2.0}
> + if self.__signature.name in override_tolerances:
> + override_tolerance = override_tolerances[self.__signature.name]
> + else:
> + override_tolerance = 0.0
> + test += 'uniform float tolerance {0}\n'.format(
> + override_tolerance)
> + test += draw
> + test += 'probe rgba {0} 0 0.0 1.0 0.0 1.0\n'.format(test_num)
> + return test
> +
> +
> +class ShaderTest(object):
> + """Class used to build a test of a single built-in. This is an
> + abstract base class--derived types should override test_prefix(),
> + make_vertex_shader(), make_fragment_shader(), and other functions
> + if necessary.
> + """
> + __metaclass__ = abc.ABCMeta
> +
> + def __init__(self, signature, test_vectors):
> + """Prepare to build a test for a single built-in. signature
> + is the signature of the built-in (a key from the
> + builtin_function.test_suite dict), and test_vectors is the
> + list of test vectors for testing the given builtin (the
> + corresponding value from the builtin_function.test_suite
> + dict).
> + """
> + self._signature = signature
> + self._test_vectors = test_vectors
> + if signature.rettype.base_type == glsl_float or signature.rettype.base_type == glsl_bool:
> + self._comparator = FloatComparator(signature)
> + else:
> + raise Exception('Unexpected rettype {0}'.format(signature.rettype))
> +
> + def glsl_version(self):
> + return self._signature.version_introduced
> +
> + def draw_command(self):
> + if self.glsl_version() >= 140:
> + return 'draw arrays GL_TRIANGLE_FAN 0 4\n'
> + else:
> + return 'draw rect -1 -1 2 2\n'
> +
> + def make_additional_requirements(self):
> + """Return a string that should be included in the test's
> + [require] section.
> + """
> + return ''
> +
> + @abc.abstractmethod
> + def test_prefix(self):
> + """Return the prefix that should be used in the test file name
> + to identify the type of test, e.g. "vs" for a vertex shader
> + test.
> + """
> +
> + def make_vertex_shader(self):
> + """Return the vertex shader for this test (or None if this
> + test doesn't require a vertex shader). No need to
> + reimplement this function in classes that don't use vertex
> + shaders.
> + """
> + return None
> +
> + def make_geometry_shader(self):
> + """Return the geometry shader for this test (or None if this
> + test doesn't require a geometry shader). No need to
> + reimplement this function in classes that don't use geometry
> + shaders.
> + """
> + return None
> +
> + def make_geometry_layout(self):
> + """Return the geometry layout for this test (or None if this
> + test doesn't require a geometry layout section). No need to
> + reimplement this function in classes that don't use geometry
> + shaders.
> + """
> + return None
> +
> + def make_fragment_shader(self):
> + """Return the fragment shader for this test (or None if this
> + test doesn't require a fragment shader). No need to
> + reimplement this function in classes that don't use fragment
> + shaders.
> + """
> + return None
> +
> + def make_compute_shader(self):
> + """Return the compute shader for this test (or None if this test
> + doesn't require a compute shader). No need to reimplement
> + this function in classes that don't use compute shaders.
> + """
> + return None
> +
> + def make_test_shader(self, additional_declarations, prefix_statements,
> + output_var, suffix_statements):
> + """Generate the shader code necessary to test the built-in.
> + additional_declarations is a string containing any
> + declarations that need to be before the main() function of the
> + shader. prefix_statements is a string containing any
> + additional statements than need to be inside the main()
> + function of the shader, before the built-in function is
> + called. output_var is the variable that the result of the
> + built-in function should be assigned to, after conversion to a
> + vec4. suffix_statements is a string containing any additional
> + statements that need to be inside the main() funciton of the
> + shader, after the built-in function is called.
> + """
> + shader = ''
> + if self._signature.extension:
> + shader += '#extension GL_{0} : require\n'.format(self._signature.extension)
> + shader += additional_declarations
> + for i in xrange(len(self._signature.argtypes)):
> + shader += 'uniform {0} arg{1};\n'.format(
> + self._signature.argtypes[i], i)
> + shader += self._comparator.make_additional_declarations()
> + shader += '\n'
> + shader += 'void main()\n'
> + shader += '{\n'
> + shader += prefix_statements
> + invocation = self._signature.template.format(
> + *['arg{0}'.format(i)
> + for i in xrange(len(self._signature.argtypes))])
> + shader += self._comparator.make_result_handler(invocation, output_var)
> + shader += suffix_statements
> + shader += '}\n'
> + return shader
> +
> + def make_test_init(self):
> + """Generate initialization for the test.
> + """
> + return ''
> +
> + def make_test(self):
> + """Make the complete shader_runner test file, and return it as
> + a string.
> + """
> + test = self.make_test_init()
> + for test_num, test_vector in enumerate(self._test_vectors):
> + for i in xrange(len(test_vector.arguments)):
> + test += 'uniform {0} arg{1} {2}\n'.format(
> + shader_runner_type(self._signature.argtypes[i]),
> + i, shader_runner_format(
> + column_major_values(test_vector.arguments[i])))
> + # Note: shader_runner uses a 250x250 window so we must
> + # ensure that test_num <= 250.
> + test += self._comparator.make_result_test(
> + test_num % 250, test_vector, self.draw_command())
> + return test
> +
> + def make_vbo_data(self):
> + # Starting with GLSL 1.40/GL 3.1, we need to use VBOs and
> + # vertex shader input bindings for our vertex data instead of
> + # the piglit drawing utilities and gl_Vertex.
> + if self.glsl_version() < 140:
> + return ""
> + vbo = '[vertex data]\n'
> + vbo += 'piglit_vertex/float/2\n'
> + vbo += '-1.0 -1.0\n'
> + vbo += ' 1.0 -1.0\n'
> + vbo += ' 1.0 1.0\n'
> + vbo += '-1.0 1.0\n'
> + vbo += '\n'
> + return vbo
> +
> + def filename(self):
> + argtype_names = '-'.join(
> + str(argtype) for argtype in self._signature.argtypes)
> + if self._signature.extension:
> + subdir = self._signature.extension.lower()
> + else:
> + subdir = 'glsl-{0:1.2f}'.format(float(self.glsl_version()) / 100)
> + return os.path.join(
> + 'spec', subdir, 'precision', 'built-in-functions',
> + '{0}-{1}-{2}{3}.shader_test'.format(
> + self.test_prefix(), self._signature.name, argtype_names,
> + self._comparator.testname_suffix()))
> +
> + def generate_shader_test(self):
> + """Generate the test and write it to the output file."""
> + shader_test = '[require]\n'
> + # ARB_shader_precision was introduced in GL 4.1 / GLSL 4.10
> + shader_test += 'GLSL >= 4.10\n'
> + shader_test += self.make_additional_requirements()
> + shader_test += '\n'
> + vs = self.make_vertex_shader()
> + if vs:
> + shader_test += '[vertex shader]\n'
> + shader_test += vs
> + shader_test += '\n'
> + gs = self.make_geometry_shader()
> + if gs:
> + shader_test += '[geometry shader]\n'
> + shader_test += gs
> + shader_test += '\n'
> + gl = self.make_geometry_layout()
> + if gl:
> + shader_test += '[geometry layout]\n'
> + shader_test += gl
> + shader_test += '\n'
> + fs = self.make_fragment_shader()
> + if fs:
> + shader_test += '[fragment shader]\n'
> + shader_test += fs
> + shader_test += '\n'
> + cs = self.make_compute_shader()
> + if cs:
> + shader_test += '[compute shader]\n'
> + shader_test += cs
> + shader_test += '\n'
> + if vs:
> + shader_test += self.make_vbo_data()
> + shader_test += '[test]\n'
> + shader_test += self.make_test()
> + filename = self.filename()
> + dirname = os.path.dirname(filename)
> + if not os.path.exists(dirname):
> + os.makedirs(dirname)
> + with open(filename, 'w') as f:
> + f.write(shader_test)
> +
> +
> +class VertexShaderTest(ShaderTest):
> + """Derived class for tests that exercise the built-in in a vertex
> + shader.
> + """
> + def test_prefix(self):
> + return 'vs'
> +
> + def make_vertex_shader(self):
> + if self.glsl_version() >= 140:
> + return self.make_test_shader(
> + 'in vec4 piglit_vertex;\n' +
> + 'out vec4 color;\n',
> + ' gl_Position = piglit_vertex;\n',
> + 'color', '')
> + else:
> + return self.make_test_shader(
> + 'attribute vec4 piglit_vertex;\n' +
> + 'varying vec4 color;\n',
> + ' gl_Position = piglit_vertex;\n',
> + 'color', '')
> +
> + def make_fragment_shader(self):
> + shader = '''varying vec4 color;
> +
> +void main()
> +{
> + gl_FragColor = color;
> +}
> +'''
> + return shader
> +
> +
> +class GeometryShaderTest(ShaderTest):
> + """Derived class for tests that exercise the built-in in a
> + geometry shader.
> + """
> + def test_prefix(self):
> + return 'gs'
> +
> + def glsl_version(self):
> + return max(150, ShaderTest.glsl_version(self))
> +
> + def make_vertex_shader(self):
> + shader = ''
> + shader += "in vec4 piglit_vertex;\n"
> + shader += "varying vec4 vertex_to_gs;\n"
> +
> + shader += "void main()\n"
> + shader += "{\n"
> + shader += " vertex_to_gs = piglit_vertex;\n"
> + shader += "}\n"
> +
> + return shader
> +
> + def make_geometry_shader(self):
> + additional_declarations = ''
> + additional_declarations += 'layout(triangles) in;\n'
> + additional_declarations \
> + += 'layout(triangle_strip, max_vertices = 3) out;\n'
> + additional_declarations += 'in vec4 vertex_to_gs[3];\n'
> + additional_declarations += 'out vec4 color;\n'
> + return self.make_test_shader(
> + additional_declarations,
> + ' vec4 tmp_color;\n',
> + 'tmp_color',
> + ' for (int i = 0; i < 3; i++) {\n'
> + ' gl_Position = vertex_to_gs[i];\n'
> + ' color = tmp_color;\n'
> + ' EmitVertex();\n'
> + ' }\n')
> +
> + def make_fragment_shader(self):
> + shader = '''varying vec4 color;
> +
> +void main()
> +{
> + gl_FragColor = color;
> +}
> +'''
> + return shader
> +
> +
> +class FragmentShaderTest(ShaderTest):
> + """Derived class for tests that exercise the built-in in a
> + fragment shader.
> + """
> + def test_prefix(self):
> + return 'fs'
> +
> + def make_vertex_shader(self):
> + shader = ""
> + shader += "attribute vec4 piglit_vertex;\n"
> + shader += "void main()\n"
> + shader += "{\n"
> + shader += " gl_Position = piglit_vertex;\n"
> + shader += "}\n"
> +
> + return shader
> +
> + def make_fragment_shader(self):
> + return self.make_test_shader('', '', 'gl_FragColor', '')
> +
> +class ComputeShaderTest(ShaderTest):
> + """Derived class for tests that exercise the built-in in a
> + compute shader.
> + """
> + def test_prefix(self):
> + return 'cs'
> +
> + def glsl_version(self):
> + return max(430, ShaderTest.glsl_version(self))
> +
> + def make_compute_shader(self):
> + additional_declarations = 'writeonly uniform image2D tex;\n'
> + additional_declarations += 'layout(local_size_x = 16, local_size_y = 16) in;\n'
> + return self.make_test_shader(
> + additional_declarations,
> + ' vec4 tmp_color;\n',
> + 'tmp_color',
> + ' ivec2 coord = ivec2(gl_GlobalInvocationID.xy);\n'
> + ' imageStore(tex, coord, tmp_color);\n')
> +
> + def make_test_init(self):
> + return '''uniform int tex 0
> +texture rgbw 0 (16, 16)
> +image texture 0
> +fb tex 2d 0
> +'''
> +
> +
> + def draw_command(self):
> + return 'compute 1 1 1\n'
> +
> +
> +def all_tests():
> + trig_names = ('sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh')
> + for signature, test_vectors in sorted(test_suite.items()):
> + # Create a bool list of all the arguments for this vector telling whether
> + # each is a float type (float, vec2, mat2, etc.) or not
> + 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()
> + if signature.rettype.base_type == glsl_float and \
> + arg_float_check and \
> + all(arg_float_check) and \
> + signature.name not in trig_names and \
> + signature.name != 'determinant':
> + yield VertexShaderTest(signature, test_vectors)
> + yield GeometryShaderTest(signature, test_vectors)
> + yield FragmentShaderTest(signature, test_vectors)
> + yield ComputeShaderTest(signature, test_vectors)
> +
> +
> +def main():
> + numpy.set_printoptions(precision=11)
> + desc = 'Generate shader tests that test built-in functions using uniforms'
> + usage = 'usage: %prog [-h] [--names-only]'
> + parser = optparse.OptionParser(description=desc, usage=usage)
> + parser.add_option(
> + '--names-only',
> + dest='names_only',
> + action='store_true',
> + help="Don't output files, just generate a list of filenames to stdout")
> + options, args = parser.parse_args()
> + for test in all_tests():
> + if not options.names_only:
> + test.generate_shader_test()
> + print test.filename()
> +
> +
> +if __name__ == '__main__':
> + main()
> diff --git a/tests/all.py b/tests/all.py
> index 3a2f4e2..d56582e 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -1061,6 +1061,9 @@ spec['glsl-1.10']['built-in constants'] = PiglitGLTest('built-in-constants ' + o
>
> spec['glsl-1.10']['api'] = {}
> add_concurrent_test(spec['glsl-1.10']['api'], 'getactiveattrib 110');
> +spec['glsl-1.10']['precision'] = {}
> +add_shader_test_dir(spec['glsl-1.10']['precision'], os.path.join(generatedTestDir, 'spec', 'glsl-1.10', 'precision'),
> + recursive=True)
>
> # Group spec/glsl-1.20
> spec['glsl-1.20'] = {}
> @@ -1135,6 +1138,10 @@ add_concurrent_test(spec['glsl-1.20']['execution'], 'tex-miplevel-selection GL2:
> add_concurrent_test(spec['glsl-1.20']['execution'], 'tex-miplevel-selection GL2:textureProj(bias) 1DShadow')
> add_concurrent_test(spec['glsl-1.20']['execution'], 'tex-miplevel-selection GL2:textureProj(bias) 2DShadow')
>
> +spec['glsl-1.20']['precision'] = {}
> +add_shader_test_dir(spec['glsl-1.20']['precision'], os.path.join(generatedTestDir, 'spec', 'glsl-1.20', 'precision'),
> + recursive=True)
> +
>
> # Group spec/glsl-1.30
> spec['glsl-1.30'] = {}
> @@ -1386,6 +1393,10 @@ add_concurrent_test(spec['glsl-1.30']['execution'], 'tex-miplevel-selection text
> add_concurrent_test(spec['glsl-1.30']['execution'], 'tex-miplevel-selection textureProjGradOffset 1DShadow')
> add_concurrent_test(spec['glsl-1.30']['execution'], 'tex-miplevel-selection textureProjGradOffset 2DShadow')
>
> +spec['glsl-1.30']['precision'] = {}
> +add_shader_test_dir(spec['glsl-1.30']['precision'], os.path.join(generatedTestDir, 'spec', 'glsl-1.30', 'precision'),
> + recursive=True)
> +
> # Group spec/glsl-1.40
> spec['glsl-1.40'] = {}
> import_glsl_parser_tests(spec['glsl-1.40'],
> @@ -1420,6 +1431,10 @@ for stage in ['vs', 'gs', 'fs']:
> 'texelFetch offset 140 {0} {1}'.format(stage, sampler),
> run_concurrent=True)
>
> +spec['glsl-1.40']['precision'] = {}
> +add_shader_test_dir(spec['glsl-1.40']['precision'], os.path.join(generatedTestDir, 'spec', 'glsl-1.40', 'precision'),
> + recursive=True)
> +
> spec['glsl-1.50'] = {}
> import_glsl_parser_tests(spec['glsl-1.50'],
> os.path.join(testsDir, 'spec', 'glsl-1.50'),
> @@ -1498,6 +1513,10 @@ for output_layout in ['points', 'lines', 'lines_adjacency', 'triangles',
> 'glsl-1.50-gs-output-layout-qualifiers {0}'.format(
> output_layout))
>
> +spec['glsl-1.50']['precision'] = {}
> +add_shader_test_dir(spec['glsl-1.50']['precision'], os.path.join(generatedTestDir, 'spec', 'glsl-1.50', 'precision'),
> + recursive=True)
> +
> spec['glsl-3.30'] = {}
> spec['glsl-3.30']['built-in constants'] = PiglitGLTest('built-in-constants ' + os.path.join(testsDir, 'spec/glsl-3.30/minimum-maximums.txt'), run_concurrent=True)
>
> --
> 2.1.2
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20141107/cfb5a84d/attachment-0001.sig>
More information about the Piglit
mailing list