This patch converts builtin_function_fp64.py to use the shared modules created by the previous patch.
It also merges some functionality previously in builtin_function_fp64 into these shared modules. Signed-off-by: Dylan Baker <[email protected]> --- generated_tests/CMakeLists.txt | 11 +- generated_tests/builtin_function_fp64.py | 545 +++------------------ generated_tests/builtins/generators.py | 7 +- generated_tests/builtins/glsl_types.py | 102 ++-- generated_tests/gen_builtin_uniform_tests_fp64.py | 42 +- .../gen_constant_array_size_tests_fp64.py | 38 +- 6 files changed, 183 insertions(+), 562 deletions(-) diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt index 96a551e..04913ae 100644 --- a/generated_tests/CMakeLists.txt +++ b/generated_tests/CMakeLists.txt @@ -109,15 +109,20 @@ piglit_make_generated_tests( gen_outerproduct_tests.py templates/gen_outerproduct_tests/template.shader_test.mako ) - piglit_make_generated_tests( builtin_uniform_tests_fp64.list gen_builtin_uniform_tests_fp64.py - builtin_function_fp64.py) + builtin_function_fp64.py + builtins/glsl_types.py + builtins/generators.py + builtins/math.py) piglit_make_generated_tests( constant_array_size_tests_fp64.list gen_constant_array_size_tests_fp64.py - builtin_function_fp64.py) + builtin_function_fp64.py + builtins/glsl_types.py + builtins/generators.py + builtins/math.py) piglit_make_generated_tests( shader_image_load_store_tests.list gen_shader_image_load_store_tests.py) diff --git a/generated_tests/builtin_function_fp64.py b/generated_tests/builtin_function_fp64.py index 992323f..f13b7e7 100644 --- a/generated_tests/builtin_function_fp64.py +++ b/generated_tests/builtin_function_fp64.py @@ -21,254 +21,39 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -# This source file defines a set of test vectors that can be used to -# test GLSL's built-in functions and operators. It is intended to be -# used by Python code that generates Piglit tests. -# -# The key export is the dictionary test_suite. It contains an entry -# for each possible overload of every pure built-in function and -# operator. By iterating through this dictionary you can find a set -# of test vectors for testing nearly every built-in GLSL function. -# -# The following functions are not included, since they are not pure, -# so they can't be tested using simple vectors: -# - dFdx() -# - dFdy() -# - fwidth() -# - ftransform() -# - Increment and decrement operators -# -# The following functions are not included, since they need to be -# tested in specialized ways: -# - modf(): not tested because it has an out parameter -# - isnan() and isinf(): not tested because special effort is required -# to create values that cause these functions to return true. -# -# Also not tested are array subscripting, field/method selection, -# swizzling, the function call operator, assignment, and the sequence -# operator. +"""This source file defines a set of test vectors that can be used to test +GLSL's built-in functions and operators. + +The key export is the dictionary test_suite. It contains an entry +for each possible overload of every pure built-in function and +operator. By iterating through this dictionary you can find a set +of test vectors for testing nearly every built-in GLSL function. + +The following functions are not included, since they are not pure, +so they can't be tested using simple vectors: +- dFdx() +- dFdy() +- fwidth() +- ftransform() +- Increment and decrement operators + +The following functions are not included, since they need to be +tested in specialized ways: +- modf(): not tested because it has an out parameter +- isnan() and isinf(): not tested because special effort is required + to create values that cause these functions to return true. + +Also not tested are array subscripting, field/method selection, +swizzling, the function call operator, assignment, and the sequence +operator. + +""" -import collections import itertools -import numpy as np - - -# Floating point types used by Python and numpy -DOUBLE_TYPES = (float, np.float64, np.float32) - -class GlslBuiltinType(object): - """Class representing a GLSL built-in type.""" - def __init__(self, name, base_type, num_cols, num_rows, - version_introduced): - self.__name = name - if base_type is not None: - self.__base_type = base_type - else: - self.__base_type = self - self.__num_cols = num_cols - self.__num_rows = num_rows - self.__version_introduced = version_introduced - - @property - def name(self): - """The name of the type, as a string.""" - return self.__name - - @property - def base_type(self): - """For vectors and matrices, the type of data stored in each - element. For scalars, equal to self. - """ - return self.__base_type - - @property - def num_cols(self): - """For matrices, the number of columns. For vectors and - scalars, 1. - """ - return self.__num_cols - - @property - def num_rows(self): - """For vectors and matrices, the number of rows. For scalars, - 1. - """ - return self.__num_rows - - @property - def is_scalar(self): - return self.__num_cols == 1 and self.__num_rows == 1 - - @property - def is_vector(self): - return self.__num_cols == 1 and self.__num_rows != 1 - - @property - def is_matrix(self): - return self.__num_cols != 1 - - @property - def version_introduced(self): - """The earliest version of GLSL that this type appears in (as - a string, e.g. 110). - """ - return self.__version_introduced - - def __str__(self): - return self.__name - - def __repr__(self): - return 'glsl_{0}'.format(self.__name) - - -# Concrete declarations of GlslBuiltinType -glsl_bool = GlslBuiltinType('bool', None, 1, 1, 110) -glsl_bvec2 = GlslBuiltinType('bvec2', glsl_bool, 1, 2, 110) -glsl_bvec3 = GlslBuiltinType('bvec3', glsl_bool, 1, 3, 110) -glsl_bvec4 = GlslBuiltinType('bvec4', glsl_bool, 1, 4, 110) -glsl_double = GlslBuiltinType('double', None, 1, 1, 400) -glsl_dvec2 = GlslBuiltinType('dvec2', glsl_double, 1, 2, 400) -glsl_dvec3 = GlslBuiltinType('dvec3', glsl_double, 1, 3, 400) -glsl_dvec4 = GlslBuiltinType('dvec4', glsl_double, 1, 4, 400) -glsl_dmat2 = GlslBuiltinType('dmat2', glsl_double, 2, 2, 400) -glsl_dmat3 = GlslBuiltinType('dmat3', glsl_double, 3, 3, 400) -glsl_dmat4 = GlslBuiltinType('dmat4', glsl_double, 4, 4, 400) -glsl_dmat2x2 = glsl_dmat2 -glsl_dmat3x2 = GlslBuiltinType('dmat3x2', glsl_double, 3, 2, 400) -glsl_dmat4x2 = GlslBuiltinType('dmat4x2', glsl_double, 4, 2, 400) -glsl_dmat2x3 = GlslBuiltinType('dmat2x3', glsl_double, 2, 3, 400) -glsl_dmat3x3 = glsl_dmat3 -glsl_dmat4x3 = GlslBuiltinType('dmat4x3', glsl_double, 4, 3, 400) -glsl_dmat2x4 = GlslBuiltinType('dmat2x4', glsl_double, 2, 4, 400) -glsl_dmat3x4 = GlslBuiltinType('dmat3x4', glsl_double, 3, 4, 400) -glsl_dmat4x4 = glsl_dmat4 - - -# Named tuple representing the signature of a single overload of a -# built-in GLSL function or operator: -# - name is a name suitable for use in test filenames. For functions, -# this is the name of the function. For operators, it is a short -# description of the operator, beginning with "op", e.g. "op-plus". -# - template is a Python format string that can be used to construct -# GLSL code that invokes the function or operator. -# - version_introduced earliest version of GLSL the test applies to -# (as a string, e.g. 110). -# - rettype is the return type of the function or operator (as a -# GlslBuiltinType). -# - argtypes is a tuple containing the types of each parameter (as -# GlslBuiltinTypes). -# -# For example, the function -# -# vec3 step(float edge, vec3 x) -# -# has a signature of -# -# Signature(name='step', template='step({0}, {1})', -# version_introduced=110, rettype='vec3', -# argtypes=('float', 'vec3')) -Signature = collections.namedtuple( - 'Signature', - ('name', 'template', 'version_introduced', 'extension', 'rettype', 'argtypes')) - - -# Named tuple representing a single piece of test data for testing a -# built-in GLSL function: -# - arguments is a tuple containing the arguments to apply to the -# function. Each argument is of a type native to numpy (e.g. -# numpy.float32 or numpy.ndarray) -# - result is the value the function is expected to return. It is -# also of a type native to numpy. -# - tolerance is a float64 representing how much deviation from the -# result we expect, considering the floating point precision -# requirements of GLSL and OpenGL. The value may be zero for test -# vectors involving booleans and integers. If result is a vector or -# matrix, tolerance should be interpreted as the maximum permissible -# RMS error (as would be computed by the distance() function). -TestVector = collections.namedtuple( - 'TestVector', ('arguments', 'result', 'tolerance')) - - -def glsl_type_of(value): - """Return the GLSL type corresponding to the given native numpy - value, as a GlslBuiltinType. - """ - - if isinstance(value, DOUBLE_TYPES): - return glsl_double - elif isinstance(value, (bool, np.bool_)): - return glsl_bool - else: - if len(value.shape) == 1: - # Vector - vector_length = value.shape[0] - assert 2 <= vector_length <= 4 - if value.dtype in DOUBLE_TYPES: - return (glsl_dvec2, glsl_dvec3, glsl_dvec4)[vector_length - 2] - elif value.dtype == bool: - return (glsl_bvec2, glsl_bvec3, glsl_bvec4)[vector_length - 2] - else: - raise Exception( - 'Unexpected vector base type {0}'.format(value.dtype)) - else: - # Matrix - assert value.dtype in DOUBLE_TYPES - assert len(value.shape) == 2 - matrix_rows = value.shape[0] - assert 2 <= matrix_rows <= 4 - matrix_columns = value.shape[1] - assert 2 <= matrix_columns <= 4 - matrix_types = ((glsl_dmat2x2, glsl_dmat2x3, glsl_dmat2x4), - (glsl_dmat3x2, glsl_dmat3x3, glsl_dmat3x4), - (glsl_dmat4x2, glsl_dmat4x3, glsl_dmat4x4)) - return matrix_types[matrix_columns - 2][matrix_rows - 2] - - -def column_major_values(value): - """Given a native numpy value, return a list of the scalar values - comprising it, in column-major order.""" - if isinstance(value, np.ndarray): - return list(np.reshape(value, -1, 'F')) - else: - return [value] - - -def glsl_constant(value): - """Given a native numpy value, return GLSL code that constructs - it.""" - column_major = np.reshape(np.array(value), -1, 'F') - if column_major.dtype == bool: - values = ['true' if x else 'false' for x in column_major] - else: - values = ['{0}lf'.format(repr(x)) for x in column_major] - if len(column_major) == 1: - return values[0] - else: - return '{0}({1})'.format(glsl_type_of(value), ', '.join(values)) - - -def round_to_32_bits(value): - """If value is a floating point type, round it down to 32 bits. - Otherwise return it unchanged. - """ - if isinstance(value, float): - return np.float32(value) - elif isinstance(value, np.ndarray) and value.dtype == np.float64: - return np.array(value, dtype=np.float32) - else: - return value +import numpy as np -def extend_to_64_bits(value): - """If value is a floating point type, extend it to 64 bits. - Otherwise return it unchanged. - """ - if isinstance(value, np.float32): - return np.float64(value) - elif isinstance(value, np.ndarray) and value.dtype == np.float32: - return np.array(value, dtype=np.float64) - else: - return value +from builtins import glsl_types, math, generators # Dictionary containing the test vectors. Each entry in the @@ -281,164 +66,12 @@ def extend_to_64_bits(value): test_suite = {} -# Implementation -# ============== -# -# The functions below shouldn't be necessary to call from outside this -# file. They exist solely to populate test_suite with test vectors. - -# Functions that simulate GLSL built-in functions (in the cases where -# the GLSL built-in functions have no python or numpy equivalent, or -# in cases where there is a behavioral difference). These functions -# return None if the behavior of the GLSL built-in is undefined for -# the given set of inputs. -def _multiply(x, y): - x_type = glsl_type_of(x) - y_type = glsl_type_of(y) - - if x_type.is_vector and y_type.is_vector: - # vector * vector is done componentwise. - return x * y - else: - # All other cases are standard linear algebraic - # multiplication, which numpy calls "dot". - return np.dot(x, y) - - -def _divide(x, y): - if any(y_element == 0 for y_element in column_major_values(y)): - # Division by zero is undefined. - return None - return x / y - - -def _modulus(x, y): - if any(x_element < 0 for x_element in column_major_values(x)): - # Modulus operation with a negative first operand is - # undefined. - return None - if any(y_element <= 0 for y_element in column_major_values(y)): - # Modulus operation with a negative or zero second operand is - # undefined. - return None - return x % y - - -def _lshift(x, y): - if not all(0 <= y_element < 32 for y_element in column_major_values(y)): - # Shifts by less than 0 or more than the number of bits in the - # type being shifted are undefined. - return None - # When the arguments to << don't have the same signedness, numpy - # likes to promote them to int64. To avoid this, convert y to be - # the same type as x. - y_orig = y - result = x << y - - # Shifting should always produce a result with the same base type - # as the left argument. - assert glsl_type_of(result).base_type == glsl_type_of(x).base_type - - return result - - -def _rshift(x, y): - if not all(0 <= y_element < 32 for y_element in column_major_values(y)): - # Shifts by less than 0 or more than the number of bits in the - # type being shifted are undefined. - return None - # When the arguments to >> don't have the same signedness, numpy - # likes to promote them to int64. To avoid this, convert y to be - # the same type as x. - y_orig = y - result = x >> y - - # Shifting should always produce a result with the same base type - # as the left argument. - assert glsl_type_of(result).base_type == glsl_type_of(x).base_type - - return result - - -def _equal(x, y): - return all(column_major_values(x == y)) - - -def _not_equal(x, y): - return not _equal(x, y) - - -def _arctan2(y, x): - if x == y == 0.0: - return None - return np.arctan2(y, x) - - -def _pow(x, y): - if x < 0.0: - return None - if x == 0.0 and y <= 0.0: - return None - return np.power(x, y) - - -def _exp2(x): - # exp2() is not available in versions of numpy < 1.3.0 so we - # emulate it with power(). - return np.power(2, x) - - -def _trunc(x): - # trunc() rounds toward zero. It is not available in version - # 1.2.1 of numpy so we emulate it with floor(), sign(), and abs(). - return np.sign(x) * np.floor(np.abs(x)) - - -def _clamp(x, minVal, maxVal): - if minVal > maxVal: - return None - return min(max(x, minVal), maxVal) - - -# Inefficient, but obvious -def _mid3(x, y, z): - return np.sort([x, y, z])[1] - -def _smoothstep(edge0, edge1, x): - if edge0 >= edge1: - return None - t = _clamp((x-edge0)/(edge1-edge0), 0.0, 1.0) - return t*t*(3.0-2.0*t) - - -def _normalize(x): - return x/np.linalg.norm(x) - - -def _faceforward(N, I, Nref): - if np.dot(Nref, I) < 0.0: - return N - else: - return -N - - -def _reflect(I, N): - return I-2*np.dot(N, I)*N - - -def _refract(I, N, eta): - k = 1.0-eta*eta*(1.0-np.dot(N, I)*np.dot(N, I)) - if k < 0.0: - return I*0.0 - else: - return eta*I-(eta*np.dot(N, I)+np.sqrt(k))*N - - def _argument_types_match(arguments, argument_indices_to_match): """Return True if all of the arguments indexed by argument_indices_to_match have the same GLSL type. """ - types = [glsl_type_of(arguments[i]) for i in argument_indices_to_match] + types = [glsl_types.glsl_type_of(arguments[i]) + for i in argument_indices_to_match] return all(x == types[0] for x in types) @@ -535,11 +168,13 @@ def _simulate_function(test_inputs, python_equivalent, tolerance_function): """ test_vectors = [] for inputs in test_inputs: - expected_output = python_equivalent(*[extend_to_64_bits(x) for x in inputs]) + expected_output = generators.extend_to_64_bits(python_equivalent( + *[generators.extend_to_64_bits(x) for x in inputs])) if expected_output is not None: tolerance = np.float64( tolerance_function(inputs, expected_output)) - test_vectors.append(TestVector(inputs, expected_output, tolerance)) + test_vectors.append( + generators.TestVector(inputs, expected_output, tolerance)) return test_vectors @@ -603,7 +238,7 @@ def _vectorize_test_vectors(test_vectors, scalar_arg_indices, vector_length): result = np.array([tv.result for tv in test_vectors]) tolerance = np.float64( np.linalg.norm([tv.tolerance for tv in test_vectors])) - return TestVector(arguments, result, tolerance) + return generators.TestVector(arguments, result, tolerance) vectorized_test_vectors = [] groups = make_groups(test_vectors) for key in sorted(groups.keys()): @@ -631,11 +266,12 @@ def _store_test_vector(test_suite_dict, name, glsl_version, extension, test_vect arg_indices = xrange(len(test_vector.arguments)) template = '{0}({1})'.format( name, ', '.join('{{{0}}}'.format(i) for i in arg_indices)) - rettype = glsl_type_of(test_vector.result) - argtypes = tuple(glsl_type_of(arg) for arg in test_vector.arguments) + rettype = glsl_types.glsl_type_of(test_vector.result) + argtypes = tuple( + glsl_types.glsl_type_of(arg) for arg in test_vector.arguments) adjusted_glsl_version = glsl_version - signature = Signature( + signature = generators.Signature( name, template, adjusted_glsl_version, extension, rettype, argtypes) if signature not in test_suite_dict: test_suite_dict[signature] = [] @@ -667,6 +303,9 @@ def make_arguments(input_generators): by taking the cartesian product of the input sequences. """ + input_generators = [ + [generators.extend_to_64_bits(x) for x in seq] + for seq in input_generators] return list(itertools.product(*input_generators)) @@ -683,9 +322,6 @@ def _make_componentwise_test_vectors(test_suite_dict): atan_inputs.append(-pow(10.0, exponent)) # Make a similar set of inputs for acosh(), except don't use any # values < 1, since acosh() is only defined for x >= 1. - acosh_inputs = [1.0 + x for x in atan_inputs if x >= 0] - ints = [np.int32(x) for x in [-5, -2, -1, 0, 1, 2, 5]] - uints = [np.uint32(x) for x in [0, 1, 2, 5, 34]] bools = [True, False] def f(name, arity, python_equivalent, @@ -742,7 +378,7 @@ def _make_componentwise_test_vectors(test_suite_dict): f('abs', 1, np.abs, None, [np.linspace(-1.5, 1.5, 5)]) f('sign', 1, np.sign, None, [np.linspace(-1.5, 1.5, 5)]) f('floor', 1, np.floor, None, [np.linspace(-2.0, 2.0, 4)]) - f('trunc', 1, _trunc, None, [np.linspace(-2.0, 2.0, 8)]) + f('trunc', 1, math.trunc, None, [np.linspace(-2.0, 2.0, 8)]) # Note: the direction of rounding used by round() is not specified # for half-integer values, so we test it over a range that doesn't @@ -764,7 +400,7 @@ def _make_componentwise_test_vectors(test_suite_dict): [np.linspace(-2.0, 2.0, 4), np.linspace(-2.0, 2.0, 4)]) f('max', 2, max, [1], [np.linspace(-2.0, 2.0, 4), np.linspace(-2.0, 2.0, 4)]) - f('clamp', 3, _clamp, [1, 2], [np.linspace(-2.0, 2.0, 4), + f('clamp', 3, math.clamp, [1, 2], [np.linspace(-2.0, 2.0, 4), np.linspace(-1.5, 1.5, 3), np.linspace(-1.5, 1.5, 3)]) f('mix', 3, lambda x, y, a: x*(1-a)+y*a, [2], [np.linspace(-2.0, 2.0, 2), np.linspace(-3.0, 3.0, 2), @@ -773,7 +409,7 @@ def _make_componentwise_test_vectors(test_suite_dict): [np.linspace(-2.0, 2.0, 2), np.linspace(-3.0, 3.0, 2), bools]) f('step', 2, lambda edge, x: 0.0 if x < edge else 1.0, [0], [np.linspace(-2.0, 2.0, 4), np.linspace(-2.0, 2.0, 4)]) - f('smoothstep', 3, _smoothstep, [0, 1], + f('smoothstep', 3, math.smoothstep, [0, 1], [np.linspace(-1.9, 1.9, 4), np.linspace(-1.9, 1.9, 4), np.linspace(-2.0, 2.0, 4)]) @@ -861,8 +497,8 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): vector/matrix with the same base type, or if they are the same type. """ - x_type = glsl_type_of(x) - y_type = glsl_type_of(y) + x_type = glsl_types.glsl_type_of(x) + y_type = glsl_types.glsl_type_of(y) if x_type.base_type != y_type.base_type: return False if x_type.is_scalar or y_type.is_scalar: @@ -877,8 +513,8 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): matrices with the same base type, and the vector/matrix sizes are properly matched. """ - x_type = glsl_type_of(x) - y_type = glsl_type_of(y) + x_type = glsl_types.glsl_type_of(x) + y_type = glsl_types.glsl_type_of(y) if x_type.base_type != y_type.base_type: return False if x_type.is_scalar or y_type.is_scalar: @@ -908,11 +544,11 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): first one is a vector and the second is a scalar. Their base types need not be the same, but they both must be integral. """ - x_type = glsl_type_of(x) - y_type = glsl_type_of(y) - if x_type.base_type not in (glsl_int, glsl_uint): + x_type = glsl_types.glsl_type_of(x) + y_type = glsl_types.glsl_type_of(y) + if x_type.base_type not in (glsl_types.GLSL_INT, glsl_types.GLSL_UINT): return False - if y_type.base_type not in (glsl_int, glsl_uint): + if y_type.base_type not in (glsl_types.GLSL_INT, glsl_types.GLSL_UINT): return False if y_type.is_scalar: return True @@ -936,66 +572,7 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): np.array([ -1.333333333333333259, 0.66, 1.87]), ] - norm_doubles_dvecs = [_normalize(x) for x in nz_doubles_dvecs] - squaremats = [ - np.array([[ 1.60, 0.76], - [ 1.53, -1.00]]), # mat2 - np.array([[-0.13, -0.87], - [-1.40, 1.40]]), # mat2 - np.array([[-1.11, 1.67, -0.41], - [ 0.13, 1.09, -0.02], - [ 0.56, 0.95, 0.24]]), # mat3 - np.array([[-1.69, -0.46, -0.18], - [-1.09, 1.75, 2.00], - [-1.53, -0.70, -1.47]]), # mat3 - np.array([[-1.00, -0.55, -1.08, 1.79], - [ 1.77, 0.62, 0.48, -1.35], - [ 0.09, -0.71, -1.39, -1.21], - [-0.91, -1.82, -1.43, 0.72]]), # mat4 - np.array([[ 0.06, 1.31, 1.52, -1.96], - [ 1.60, -0.32, 0.51, -1.84], - [ 1.25, 0.45, 1.90, -0.72], - [-0.16, 0.45, -0.88, 0.39]]), # mat4 - ] - mats = squaremats + [ - np.array([[ 0.09, 1.30, 1.25], - [-1.19, 0.08, 1.08]]), # mat3x2 - np.array([[-0.36, -1.08, -0.60], - [-0.53, 0.88, -1.79]]), # mat3x2 - np.array([[-0.46, 1.94], - [-0.45, -0.75], - [ 1.03, -0.50]]), # mat2x3 - np.array([[ 1.38, -1.08], - [-1.27, 1.83], - [ 1.00, -0.74]]), # mat2x3 - np.array([[ 1.81, -0.87, 0.81, 0.65], - [-1.16, -1.52, 0.25, -1.51]]), # mat4x2 - np.array([[ 1.93, -1.63, 0.29, 1.60], - [ 0.49, 0.27, 0.14, 0.94]]), # mat4x2 - np.array([[ 0.16, -1.69], - [-0.80, 0.59], - [-1.74, -1.43], - [-0.02, -1.21]]), # mat2x4 - np.array([[-1.02, 0.74], - [-1.64, -0.13], - [-1.59, 0.47], - [ 0.30, 1.13]]), # mat2x4 - np.array([[-0.27, -1.38, -1.41, -0.12], - [-0.17, -0.56, 1.47, 1.86], - [-1.85, -1.29, 1.77, 0.01]]), # mat4x3 - np.array([[-0.47, -0.15, 1.97, -1.05], - [-0.20, 0.53, -1.82, -1.41], - [-1.39, -0.19, 1.62, 1.58]]), # mat4x3 - np.array([[ 1.42, -0.86, 0.27], - [ 1.80, -1.74, 0.04], - [-1.88, -0.37, 0.43], - [ 1.37, 1.90, 0.71]]), # mat3x4 - np.array([[-1.72, 0.09, 0.45], - [-0.31, -1.58, 1.92], - [ 0.14, 0.18, -0.56], - [ 0.40, -0.77, 1.76]]), # mat3x4 - ] - + norm_doubles_dvecs = [math.normalize(x) for x in nz_doubles_dvecs] dsquaredmats = [ np.array([[ 1.60, 0.76], [ 1.53, -1.00]]), # mat2 @@ -1104,11 +681,11 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): [doubles+dvecs+dmats, doubles+dvecs+dmats], template='({0} - {1})') - f('op-mult', 2, _multiply, match_multiply, + f('op-mult', 2, math.multiply, match_multiply, [doubles+dvecs+dmats, doubles+dvecs+dmats], template='({0} * {1})') - f('op-div', 2, _divide, match_simple_binop, + f('op-div', 2, math.divide, match_simple_binop, [doubles+dvecs+dmats, doubles+dvecs+dmats], template='({0} / {1})') @@ -1118,12 +695,12 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict): f('dot', 2, np.dot, match_args(0, 1), [doubles+dvecs, doubles+dvecs]) f('cross', 2, np.cross, match_args(0, 1), [dvec3s, dvec3s], _cross_product_tolerance) - f('normalize', 1, _normalize, None, [nz_doubles_dvecs]) - f('faceforward', 3, _faceforward, match_args(0, 1, 2), + f('normalize', 1, math.normalize, None, [nz_doubles_dvecs]) + f('faceforward', 3, math.faceforward, match_args(0, 1, 2), [doubles+dvecs, doubles+dvecs, doubles+dvecs]) - f('reflect', 2, _reflect, match_args(0, 1), + f('reflect', 2, math.reflect, match_args(0, 1), [doubles+dvecs, norm_doubles_dvecs]) - f('refract', 3, _refract, match_args(0, 1), + f('refract', 3, math.refract, match_args(0, 1), [norm_doubles_dvecs, norm_doubles_dvecs, [0.5, 2.0]]) f('matrixCompMult', 2, lambda x, y: x*y, match_args(0, 1), [dmats, dmats]) diff --git a/generated_tests/builtins/generators.py b/generated_tests/builtins/generators.py index b556e77..c3536a3 100644 --- a/generated_tests/builtins/generators.py +++ b/generated_tests/builtins/generators.py @@ -91,6 +91,8 @@ def glsl_constant(value): values = ['true' if x else 'false' for x in column_major] elif column_major.dtype in glsl_types.UINT32_TYPES: values = [repr(x) + 'u' for x in column_major] + elif column_major.dtype == np.float64: + values = [repr(x) + 'lf' for x in column_major] else: values = [repr(x) for x in column_major] if len(column_major) == 1: @@ -104,6 +106,7 @@ def round_to_32_bits(value): """If value is a floating point type, round it down to 32 bits. Otherwise return it unchanged. """ + # numpy.float64 is a float if isinstance(value, float): return np.float32(value) elif isinstance(value, np.ndarray) and value.dtype == np.float64: @@ -116,7 +119,9 @@ def extend_to_64_bits(value): """If value is a floating point type, extend it to 64 bits. Otherwise return it unchanged. """ - if isinstance(value, np.float32): + # numpy.float32 is not float, so we need to explicitly check for that type + # and convert to float64 + if isinstance(value, (float, np.float32)): return np.float64(value) elif isinstance(value, np.ndarray) and value.dtype == np.float32: return np.array(value, dtype=np.float64) diff --git a/generated_tests/builtins/glsl_types.py b/generated_tests/builtins/glsl_types.py index 7d8e361..084dcda 100644 --- a/generated_tests/builtins/glsl_types.py +++ b/generated_tests/builtins/glsl_types.py @@ -25,9 +25,6 @@ import numpy as np -# Floating point types used by Python and numpy -FLOATING_TYPES = (float, np.float64, np.float32) - # Due to a bug in the Windows implementation of numpy, there are # multiple int32 types (and multiple uint32 types). So we have to # find them all when doing isinstance checks. The following code will @@ -109,40 +106,58 @@ class GlslBuiltinType(object): # Concrete declarations of GlslBuiltinType # pylint: disable=bad-whitespace -GLSL_BOOL = GlslBuiltinType('bool', None, 1, 1, 110) -GLSL_INT = GlslBuiltinType('int', None, 1, 1, 110) -GLSL_UINT = GlslBuiltinType('uint', None, 1, 1, 130) -GLSL_FLOAT = GlslBuiltinType('float', None, 1, 1, 110) -GLSL_VEC2 = GlslBuiltinType('vec2', GLSL_FLOAT, 1, 2, 110) -GLSL_VEC3 = GlslBuiltinType('vec3', GLSL_FLOAT, 1, 3, 110) -GLSL_VEC4 = GlslBuiltinType('vec4', GLSL_FLOAT, 1, 4, 110) -GLSL_BVEC2 = GlslBuiltinType('bvec2', GLSL_BOOL, 1, 2, 110) -GLSL_BVEC3 = GlslBuiltinType('bvec3', GLSL_BOOL, 1, 3, 110) -GLSL_BVEC4 = GlslBuiltinType('bvec4', GLSL_BOOL, 1, 4, 110) -GLSL_IVEC2 = GlslBuiltinType('ivec2', GLSL_INT, 1, 2, 110) -GLSL_IVEC3 = GlslBuiltinType('ivec3', GLSL_INT, 1, 3, 110) -GLSL_IVEC4 = GlslBuiltinType('ivec4', GLSL_INT, 1, 4, 110) -GLSL_UVEC2 = GlslBuiltinType('uvec2', GLSL_UINT, 1, 2, 130) -GLSL_UVEC3 = GlslBuiltinType('uvec3', GLSL_UINT, 1, 3, 130) -GLSL_UVEC4 = GlslBuiltinType('uvec4', GLSL_UINT, 1, 4, 130) -GLSL_MAT2 = GlslBuiltinType('mat2', GLSL_FLOAT, 2, 2, 110) -GLSL_MAT3 = GlslBuiltinType('mat3', GLSL_FLOAT, 3, 3, 110) -GLSL_MAT4 = GlslBuiltinType('mat4', GLSL_FLOAT, 4, 4, 110) -GLSL_MAT2X2 = GLSL_MAT2 -GLSL_MAT3X2 = GlslBuiltinType('mat3x2', GLSL_FLOAT, 3, 2, 120) -GLSL_MAT4X2 = GlslBuiltinType('mat4x2', GLSL_FLOAT, 4, 2, 120) -GLSL_MAT2X3 = GlslBuiltinType('mat2x3', GLSL_FLOAT, 2, 3, 120) -GLSL_MAT3X3 = GLSL_MAT3 -GLSL_MAT4X3 = GlslBuiltinType('mat4x3', GLSL_FLOAT, 4, 3, 120) -GLSL_MAT2X4 = GlslBuiltinType('mat2x4', GLSL_FLOAT, 2, 4, 120) -GLSL_MAT3X4 = GlslBuiltinType('mat3x4', GLSL_FLOAT, 3, 4, 120) -GLSL_MAT4X4 = GLSL_MAT4 +GLSL_BOOL = GlslBuiltinType('bool', None, 1, 1, 110) +GLSL_INT = GlslBuiltinType('int', None, 1, 1, 110) +GLSL_UINT = GlslBuiltinType('uint', None, 1, 1, 130) +GLSL_FLOAT = GlslBuiltinType('float', None, 1, 1, 110) +GLSL_VEC2 = GlslBuiltinType('vec2', GLSL_FLOAT, 1, 2, 110) +GLSL_VEC3 = GlslBuiltinType('vec3', GLSL_FLOAT, 1, 3, 110) +GLSL_VEC4 = GlslBuiltinType('vec4', GLSL_FLOAT, 1, 4, 110) +GLSL_BVEC2 = GlslBuiltinType('bvec2', GLSL_BOOL, 1, 2, 110) +GLSL_BVEC3 = GlslBuiltinType('bvec3', GLSL_BOOL, 1, 3, 110) +GLSL_BVEC4 = GlslBuiltinType('bvec4', GLSL_BOOL, 1, 4, 110) +GLSL_IVEC2 = GlslBuiltinType('ivec2', GLSL_INT, 1, 2, 110) +GLSL_IVEC3 = GlslBuiltinType('ivec3', GLSL_INT, 1, 3, 110) +GLSL_IVEC4 = GlslBuiltinType('ivec4', GLSL_INT, 1, 4, 110) +GLSL_UVEC2 = GlslBuiltinType('uvec2', GLSL_UINT, 1, 2, 130) +GLSL_UVEC3 = GlslBuiltinType('uvec3', GLSL_UINT, 1, 3, 130) +GLSL_UVEC4 = GlslBuiltinType('uvec4', GLSL_UINT, 1, 4, 130) +GLSL_MAT2 = GlslBuiltinType('mat2', GLSL_FLOAT, 2, 2, 110) +GLSL_MAT3 = GlslBuiltinType('mat3', GLSL_FLOAT, 3, 3, 110) +GLSL_MAT4 = GlslBuiltinType('mat4', GLSL_FLOAT, 4, 4, 110) +GLSL_MAT2X2 = GLSL_MAT2 +GLSL_MAT3X2 = GlslBuiltinType('mat3x2', GLSL_FLOAT, 3, 2, 120) +GLSL_MAT4X2 = GlslBuiltinType('mat4x2', GLSL_FLOAT, 4, 2, 120) +GLSL_MAT2X3 = GlslBuiltinType('mat2x3', GLSL_FLOAT, 2, 3, 120) +GLSL_MAT3X3 = GLSL_MAT3 +GLSL_MAT4X3 = GlslBuiltinType('mat4x3', GLSL_FLOAT, 4, 3, 120) +GLSL_MAT2X4 = GlslBuiltinType('mat2x4', GLSL_FLOAT, 2, 4, 120) +GLSL_MAT3X4 = GlslBuiltinType('mat3x4', GLSL_FLOAT, 3, 4, 120) +GLSL_MAT4X4 = GLSL_MAT4 +GLSL_DOUBLE = GlslBuiltinType('double', None, 1, 1, 400) +GLSL_DVEC2 = GlslBuiltinType('dvec2', GLSL_DOUBLE, 1, 2, 400) +GLSL_DVEC3 = GlslBuiltinType('dvec3', GLSL_DOUBLE, 1, 3, 400) +GLSL_DVEC4 = GlslBuiltinType('dvec4', GLSL_DOUBLE, 1, 4, 400) +GLSL_DMAT2 = GlslBuiltinType('dmat2', GLSL_DOUBLE, 2, 2, 400) +GLSL_DMAT3 = GlslBuiltinType('dmat3', GLSL_DOUBLE, 3, 3, 400) +GLSL_DMAT4 = GlslBuiltinType('dmat4', GLSL_DOUBLE, 4, 4, 400) +GLSL_DMAT2X2 = GLSL_DMAT2 +GLSL_DMAT3X2 = GlslBuiltinType('dmat3x2', GLSL_DOUBLE, 3, 2, 400) +GLSL_DMAT4X2 = GlslBuiltinType('dmat4x2', GLSL_DOUBLE, 4, 2, 400) +GLSL_DMAT2X3 = GlslBuiltinType('dmat2x3', GLSL_DOUBLE, 2, 3, 400) +GLSL_DMAT3X3 = GLSL_DMAT3 +GLSL_DMAT4X3 = GlslBuiltinType('dmat4x3', GLSL_DOUBLE, 4, 3, 400) +GLSL_DMAT2X4 = GlslBuiltinType('dmat2x4', GLSL_DOUBLE, 2, 4, 400) +GLSL_DMAT3X4 = GlslBuiltinType('dmat3x4', GLSL_DOUBLE, 3, 4, 400) +GLSL_DMAT4X4 = GLSL_DMAT4 def glsl_type_of(value): # pylint: disable=too-many-return-statements """Factory function that returns a GlslBuiltinType for native types.""" - if isinstance(value, FLOATING_TYPES): + if isinstance(value, np.float32): return GLSL_FLOAT + elif isinstance(value, np.float64): + return GLSL_DOUBLE elif isinstance(value, (bool, np.bool_)): return GLSL_BOOL elif isinstance(value, INT32_TYPES): @@ -150,13 +165,17 @@ def glsl_type_of(value): # pylint: disable=too-many-return-statements elif isinstance(value, UINT32_TYPES): return GLSL_UINT else: + assert type(value) != float, type(value) assert isinstance(value, np.ndarray) if len(value.shape) == 1: # Vector vector_length = value.shape[0] assert 2 <= vector_length <= 4 - if value.dtype in FLOATING_TYPES: + + if value.dtype == np.float32: return (GLSL_VEC2, GLSL_VEC3, GLSL_VEC4)[vector_length - 2] + elif value.dtype == np.float64: + return (GLSL_DVEC2, GLSL_DVEC3, GLSL_DVEC4)[vector_length - 2] elif value.dtype == bool: return (GLSL_BVEC2, GLSL_BVEC3, GLSL_BVEC4)[vector_length - 2] elif value.dtype in INT32_TYPES: @@ -168,13 +187,20 @@ def glsl_type_of(value): # pylint: disable=too-many-return-statements 'Unexpected vector base type {0}'.format(value.dtype)) else: # Matrix - assert value.dtype in FLOATING_TYPES + assert value.dtype in (np.float32, np.float64) assert len(value.shape) == 2 + matrix_rows = value.shape[0] - assert 2 <= matrix_rows <= 4 matrix_columns = value.shape[1] + assert 2 <= matrix_rows <= 4 assert 2 <= matrix_columns <= 4 - matrix_types = ((GLSL_MAT2X2, GLSL_MAT2X3, GLSL_MAT2X4), - (GLSL_MAT3X2, GLSL_MAT3X3, GLSL_MAT3X4), - (GLSL_MAT4X2, GLSL_MAT4X3, GLSL_MAT4X4)) + + if value.dtype == np.float32: + matrix_types = ((GLSL_MAT2X2, GLSL_MAT2X3, GLSL_MAT2X4), + (GLSL_MAT3X2, GLSL_MAT3X3, GLSL_MAT3X4), + (GLSL_MAT4X2, GLSL_MAT4X3, GLSL_MAT4X4)) + elif value.dtype == np.float64: + matrix_types = ((GLSL_DMAT2X2, GLSL_DMAT2X3, GLSL_DMAT2X4), + (GLSL_DMAT3X2, GLSL_DMAT3X3, GLSL_DMAT3X4), + (GLSL_DMAT4X2, GLSL_DMAT4X3, GLSL_DMAT4X4)) return matrix_types[matrix_columns - 2][matrix_rows - 2] diff --git a/generated_tests/gen_builtin_uniform_tests_fp64.py b/generated_tests/gen_builtin_uniform_tests_fp64.py index ec12650..120e4bb 100644 --- a/generated_tests/gen_builtin_uniform_tests_fp64.py +++ b/generated_tests/gen_builtin_uniform_tests_fp64.py @@ -44,13 +44,15 @@ # With the optional argument --names-only, it only outputs the names # of the files; it doesn't generate them. -from builtin_function_fp64 import * +from __future__ import absolute_import import abc -import numpy import optparse import os -import os.path -import sys + +import numpy as np + +from builtins import glsl_types, generators +import builtin_function_fp64 def compute_offset_and_scale(test_vectors): @@ -60,8 +62,8 @@ def compute_offset_and_scale(test_vectors): used to transform the test vectors so that their outputs can be stored in gl_FragColor without overflow. """ - low = min(numpy.min(tv.result) for tv in test_vectors) - hi = max(numpy.max(tv.result) for tv in test_vectors) + low = min(np.min(tv.result) for tv in test_vectors) + hi = max(np.max(tv.result) for tv in test_vectors) span = hi - low center = (hi + low)/2.0 span *= 2.0 @@ -92,7 +94,7 @@ def shader_runner_type(glsl_type): 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.base_type == glsl_types.GLSL_BOOL: if glsl_type.is_scalar: return 'int' else: @@ -162,7 +164,7 @@ class BoolComparator(Comparator): floats representing the expected color produced by the test. """ value = value*1.0 # convert bools to floats - value = column_major_values(value) + value = generators.column_major_values(value) value += [0.0] * self.__padding return value @@ -186,7 +188,7 @@ class BoolIfComparator(Comparator): output_var = vecp(0.0, 0.0, 1.0, 1.0); """ def __init__(self, signature): - assert signature.rettype == glsl_bool + assert signature.rettype == glsl_types.GLSL_BOOL self.__padding = 4 - signature.rettype.num_rows def make_result_handler(self, invocation, output_var): @@ -246,7 +248,8 @@ class IntComparator(Comparator): 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))) + shader_runner_format( + generators.column_major_values(test_vector.result))) test += draw test += 'probe rgba {0} 0 0.0 1.0 0.0 1.0\n'.format(test_num) return test @@ -313,7 +316,8 @@ class FloatComparator(Comparator): 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))) + shader_runner_format( + generators.column_major_values(test_vector.result))) test += 'uniform double tolerance {0}\n'.format( shader_runner_format([test_vector.tolerance])) test += draw @@ -345,9 +349,9 @@ class ShaderTest(object): self._test_vectors = test_vectors if use_if: self._comparator = BoolIfComparator(signature) - elif signature.rettype.base_type == glsl_bool: + elif signature.rettype.base_type == glsl_types.GLSL_BOOL: self._comparator = BoolComparator(signature) - elif signature.rettype.base_type == glsl_double: + elif signature.rettype.base_type == glsl_types.GLSL_DOUBLE: self._comparator = FloatComparator(signature) else: raise Exception('Unexpected rettype {0}'.format(signature.rettype)) @@ -444,7 +448,7 @@ class ShaderTest(object): 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]))) + generators.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( @@ -622,12 +626,12 @@ class FragmentShaderTest(ShaderTest): def all_tests(): for use_if in [False, True]: - for signature, test_vectors in sorted(test_suite.items()): - if use_if and signature.rettype != glsl_bool: + for signature, vectors in builtin_function_fp64.test_suite.iteritems(): + if use_if and signature.rettype != glsl_types.GLSL_BOOL: continue - yield VertexShaderTest(signature, test_vectors, use_if) - yield GeometryShaderTest(signature, test_vectors, use_if) - yield FragmentShaderTest(signature, test_vectors, use_if) + yield VertexShaderTest(signature, vectors, use_if) + yield GeometryShaderTest(signature, vectors, use_if) + yield FragmentShaderTest(signature, vectors, use_if) def main(): diff --git a/generated_tests/gen_constant_array_size_tests_fp64.py b/generated_tests/gen_constant_array_size_tests_fp64.py index a54598b..10e93d5 100644 --- a/generated_tests/gen_constant_array_size_tests_fp64.py +++ b/generated_tests/gen_constant_array_size_tests_fp64.py @@ -34,11 +34,14 @@ # With the optional argument --names-only, it only outputs the names # of the files; it doesn't generate them. -from builtin_function_fp64 import * +from __future__ import absolute_import import abc import optparse import os -import os.path + +from builtins import glsl_types, generators + +import builtin_function_fp64 class ParserTest(object): @@ -101,8 +104,8 @@ class ParserTest(object): correct result for the given test vector, and false if not. """ invocation = self.__signature.template.format( - *[glsl_constant(x) for x in test_vector.arguments]) - if self.__signature.rettype.base_type == glsl_double: + *[generators.glsl_constant(x) for x in test_vector.arguments]) + if self.__signature.rettype.base_type == glsl_types.GLSL_DOUBLE: # Test floating-point values within tolerance if self.__signature.name == 'distance': # Don't use the distance() function to test itself. @@ -119,15 +122,15 @@ class ParserTest(object): for col in xrange(self.__signature.rettype.num_cols): terms.append('(distance({0}[{1}], {2}) * distance({0}[{1}], {2}))'.format( invocation, col, - glsl_constant(test_vector.result[:, col]))) + generators.glsl_constant(test_vector.result[:, col]))) rss_distance = ' + '.join(terms) sq_tolerance = test_vector.tolerance * test_vector.tolerance return '{0} <= {1}'.format( - rss_distance, glsl_constant(sq_tolerance)) + rss_distance, generators.glsl_constant(sq_tolerance)) else: return 'distance({0}, {1}) <= {2}'.format( - invocation, glsl_constant(test_vector.result), - glsl_constant(test_vector.tolerance)) + invocation, generators.glsl_constant(test_vector.result), + generators.glsl_constant(test_vector.tolerance)) else: # Test non-floating point values exactly assert not self.__signature.rettype.is_matrix @@ -138,14 +141,14 @@ class ParserTest(object): for row in xrange(self.__signature.rettype.num_rows): terms.append('{0}[{1}] == {2}'.format( invocation, row, - glsl_constant(test_vector.result[row]))) + generators.glsl_constant(test_vector.result[row]))) return ' && '.join(terms) elif self.__signature.rettype.is_vector: return 'all(equal({0}, {1}))'.format( - invocation, glsl_constant(test_vector.result)) + invocation, generators.glsl_constant(test_vector.result)) else: return '{0} == {1}'.format( - invocation, glsl_constant(test_vector.result)) + invocation, generators.glsl_constant(test_vector.result)) def make_shader(self): """Generate the shader code necessary to test the built-in.""" @@ -193,8 +196,9 @@ class ParserTest(object): for test_vector in self.__test_vectors: parser_test += ' * {0} => {1}\n'.format( self.__signature.template.format( - *[glsl_constant(arg) for arg in test_vector.arguments]), - glsl_constant(test_vector.result)) + *[generators.glsl_constant(arg) + for arg in test_vector.arguments]), + generators.glsl_constant(test_vector.result)) parser_test += ' */\n' parser_test += self.make_shader() filename = self.filename() @@ -242,10 +246,10 @@ class FragmentParserTest(ParserTest): def all_tests(): - for signature, test_vectors in sorted(test_suite.items()): - yield VertexParserTest(signature, test_vectors) - yield GeometryParserTest(signature, test_vectors) - yield FragmentParserTest(signature, test_vectors) + for signature, vectors in builtin_function_fp64.test_suite.iteritems(): + yield VertexParserTest(signature, vectors) + yield GeometryParserTest(signature, vectors) + yield FragmentParserTest(signature, vectors) def main(): -- 2.2.0 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
