[Piglit] [PATCH] Add operator tests to auto-generated built-in function tests.

Paul Berry stereotype441 at gmail.com
Thu Aug 11 14:14:50 PDT 2011


This patch adds tests for the following built-in GLSL operators:

- op-add, op-sub, op-mult, op-div: binary arithemetic operators on
  floats, vecs, mats, ints, and ivecs.

- op-uplus, op-neg: unary arithmetic operators on floats, vecs, mats,
  ints, and ivecs.

- op-gt, op-lt, op-ge, op-le: comparison operators on ints and floats.

- op-eq, op-ne: equality and inequality comparison on any GLSL 1.20 type.

- op-and, op-or, op-xor: logical operations on bools.

- op-not: unary logical not on bools.

- op-selection: trinary selection operator (x?y:z), where the first
  argument is a bool and the second and third arguments are any GLSL
  1.20 type.

Note that implicit type conversions are not tested.  So, for instance,
int * ivec is tested, but float * ivec is not.  This was in an effort
to avoid generating an outrageous number of tests.

Note also that the "shortcut" behavior of logical and/or and trinary
selection is not tested.

These tests leverage the same test generation framework used to test
built-in functions, so the tests exercise vertex shaders, fragment
shaders, and constant folding.

All in all 1332 tests are added, in the subtrees
spec/glsl-1.{10,20}/{compiler,execution}/built-in-functions.
---
 generated_tests/builtin_function.py              |  275 ++++++++++++++++++----
 generated_tests/gen_builtin_uniform_tests.py     |   39 +++-
 generated_tests/gen_constant_array_size_tests.py |   23 +-
 3 files changed, 268 insertions(+), 69 deletions(-)

diff --git a/generated_tests/builtin_function.py b/generated_tests/builtin_function.py
index 7a42441..4bc1d88 100644
--- a/generated_tests/builtin_function.py
+++ b/generated_tests/builtin_function.py
@@ -22,17 +22,25 @@
 # DEALINGS IN THE SOFTWARE.
 
 # This source file defines a set of test vectors that can be used to
-# test GLSL's built-in functions.  It is intended to be used by
-# Python code that generates Piglit tests.
+# 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.  By
-# iterating through this dictionary you can find a set of test vectors
-# for testing nearly every built-in GLSL function.  Notable exceptions
-# include the fragment shader functions dFdx(), dFdy(), and fwidth(),
-# the texture lookup functions, and the ftransform() function, since
-# they are not pure, so they can't be tested using simple test
-# vectors.
+# 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 and operators 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
+#
+# Also not tested are array subscripting, field/method selection,
+# swizzling, the function call operator, assignment, and the sequence
+# operator.
 
 import collections
 import itertools
@@ -140,13 +148,18 @@ glsl_mat4x4 = glsl_mat4
 
 
 # Named tuple representing the signature of a single overload of a
-# built-in GLSL function:
-# - name is the function name.
+# 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. '1.10').
-# - rettype is the return type of the function (as a GlslBuiltinType).
-# - argtypes is a tuple containing the types of each function
-#   parameter (as GlslBuiltinTypes).
+# - 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
 #
@@ -154,10 +167,12 @@ glsl_mat4x4 = glsl_mat4
 #
 # has a signature of
 #
-# Signature(name='step', version_introduced='1.10', rettype='vec3',
+# Signature(name='step', template='step({0}, {1})',
+#           version_introduced='1.10', rettype='vec3',
 #           argtypes=('float', 'vec3'))
 Signature = collections.namedtuple(
-    'Signature', ('name', 'version_introduced', 'rettype', 'argtypes'))
+    'Signature',
+    ('name', 'template', 'version_introduced', 'rettype', 'argtypes'))
 
 
 
@@ -292,6 +307,41 @@ test_suite = {}
 # 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
+    if glsl_type_of(x).base_type == glsl_int:
+	# The GLSL spec does not make it clear what the rounding rules
+	# are when performing integer division.  C99 requires
+	# round-toward-zero, so in the absence of any other
+	# information, assume that's the correct behavior for GLSL.
+	#
+	# Python and numpy's rounding rules are inconsistent, so to
+	# make sure we get round-toward-zero behavior, divide the
+	# absolute values of x and y, and then fix the sign.
+	return (np.abs(x) // np.abs(y)) * (np.sign(x) * np.sign(y))
+    else:
+	return x / y
+
+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
@@ -521,7 +571,8 @@ def _vectorize_test_vectors(test_vectors, scalar_arg_indices, vector_length):
 
 
 
-def _store_test_vector(test_suite_dict, name, glsl_version, test_vector):
+def _store_test_vector(test_suite_dict, name, glsl_version, test_vector,
+		       template = None):
     """Store a test vector in the appropriate place in
     test_suite_dict.  The dictionary key (which is a Signature tuple)
     is generated by consulting the argument and return types of the
@@ -529,25 +580,38 @@ def _store_test_vector(test_suite_dict, name, glsl_version, test_vector):
 
     glsl_version is adjusted if necessary to reflect when the argument
     and return types were introduced into GLSL.
+
+    If template is supplied, it is used insted as the template for the
+    Signature objects generated.
     """
+    if template is None:
+	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)
     adjusted_glsl_version = max(
 	glsl_version, rettype.version_introduced,
 	*[t.version_introduced for t in argtypes])
-    signature = Signature(name, adjusted_glsl_version, rettype, argtypes)
+    signature = Signature(
+	name, template, adjusted_glsl_version, rettype, argtypes)
     if signature not in test_suite_dict:
 	test_suite_dict[signature] = []
     test_suite_dict[signature].append(test_vector)
 
 
 
-def _store_test_vectors(test_suite_dict, name, glsl_version, test_vectors):
+def _store_test_vectors(test_suite_dict, name, glsl_version, test_vectors,
+			template = None):
     """Store multiple test vectors in the appropriate places in
     test_suite_dict.
+
+    If template is supplied, it is used insted as the template for the
+    Signature objects generated.
     """
     for test_vector in test_vectors:
-	_store_test_vector(test_suite_dict, name, glsl_version, test_vector)
+	_store_test_vector(test_suite_dict, name, glsl_version, test_vector,
+			   template = template)
 
 
 
@@ -707,9 +771,81 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict):
     that operate on vectors/matrices as a whole.  Examples include
     length(), dot(), cross(), normalize(), and refract().
     """
-    _std_vectors = [
-	-1.33,
-	 0.85,
+    def match_args(*indices):
+	"""Return a function that determines whether the type of the
+	arguments at the given indices match.
+
+	For example:
+
+            match(1, 3)
+
+	is equivalent to:
+
+            lambda a, b, c, d: glsl_type_of(b) == glsl_type_of(d)
+	"""
+	return lambda *args: _argument_types_match(args, indices)
+    def match_simple_binop(x, y):
+	"""Detemine whether the type of the arguments is compatible
+	for a simple binary operator (such as '+').
+
+	Arguments are compatible if one is a scalar and the other is a
+	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)
+	if x_type.base_type != y_type.base_type:
+	    return False
+	if x_type.is_scalar or y_type.is_scalar:
+	    return True
+	return x_type == y_type
+    def match_multiply(x, y):
+	"""Determine whether the type of the arguments is compatible
+	for multiply.
+
+	Arguments are compatible if they are scalars, vectors, or
+	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)
+	if x_type.base_type != y_type.base_type:
+	    return False
+	if x_type.is_scalar or y_type.is_scalar:
+	    return True
+	if x_type.is_vector and y_type.is_matrix:
+	    # When multiplying vector * matrix, the vector is
+	    # transposed to a row vector.  So its row count must match
+	    # the row count of the matrix.
+	    return x_type.num_rows == y_type.num_rows
+	elif x_type.is_vector:
+	    assert y_type.is_vector
+	    # When multiplying vector * vector, the multiplication is
+	    # done componentwise, so the types must match exactly.
+	    return x_type == y_type
+	else:
+	    assert x_type.is_matrix
+	    # When multiplying matrix * matrix or matrix * vector, a
+	    # standard linear algebraic multiply is used, so x's
+	    # column count must match y's row count.
+	    return x_type.num_cols == y_type.num_rows
+
+    bools = [False, True]
+    bvecs = [np.array(bs) for bs in itertools.product(bools, bools)] + \
+	[np.array(bs) for bs in itertools.product(bools, bools, bools)] + \
+	[np.array(bs) for bs in itertools.product(bools, bools, bools, bools)]
+    ints = [12, -6, 74, -32, 0]
+    ivecs = [
+	np.array([38, 35]),
+	np.array([64, -9]),
+	np.array([-36, 32, -88]),
+	np.array([59, 77, 68]),
+	np.array([-66, 72, 87, -75]),
+	np.array([-24, 40, -23, 74])
+	]
+    nz_floats = [-1.33, 0.85]
+    floats = [0.0] + nz_floats
+    vecs = [
 	 np.array([-0.10, -1.20]),
 	 np.array([-0.42, 0.48]),
 	 np.array([-0.03, -0.85, -0.94]),
@@ -717,13 +853,13 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict):
 	 np.array([-1.65, 1.33, 1.93, 0.76]),
 	 np.array([0.80, -0.15, -0.51, 0.0])
 	 ]
-    _std_vectors3 = [
+    nz_floats_vecs = nz_floats + vecs
+    vec3s = [
 	np.array([-0.03, -0.85, -0.94]),
 	np.array([1.67, 0.66, 1.87]),
 	]
-    _normalized_vectors = [_normalize(x) for x in _std_vectors]
-    _nontrivial_vectors = [x for x in _std_vectors if not isinstance(x, FLOATING_TYPES)]
-    _std_matrices = [
+    norm_floats_vecs = [_normalize(x) for x in nz_floats_vecs]
+    mats = [
 	np.array([[ 1.60,  0.76],
 		  [ 1.53, -1.00]]), # mat2
 	np.array([[-0.13, -0.87],
@@ -779,13 +915,9 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict):
 		  [ 0.14,  0.18, -0.56],
 		  [ 0.40, -0.77,  1.76]]), # mat3x4
 	]
-    _ft = [False, True]
-    _bvecs = [np.array(bs) for bs in itertools.product(_ft, _ft)] + \
-	[np.array(bs) for bs in itertools.product(_ft, _ft, _ft)] + \
-	[np.array(bs) for bs in itertools.product(_ft, _ft, _ft, _ft)]
     def f(name, arity, glsl_version, python_equivalent,
-	  argument_indices_to_match, test_inputs,
-	  tolerance_function = _strict_tolerance):
+	  filter, test_inputs, tolerance_function = _strict_tolerance,
+	  template = None):
 	"""Make test vectors for the function with the given name and
 	arity, which was introduced in the given glsl_version.
 
@@ -794,9 +926,9 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict):
 	output of the GLSL function is undefined.  However, it need not
 	check that the lengths of the input vectors are all the same.
 
-	If argument_indices_to_match is not None, it is a sequence of
-	argument indices indicating which arguments of the function
-	need to have matching types.
+	If filter is not None, it will be called with each set of
+	arguments, and test cases will only be generated if the filter
+	returns True.
 
 	test_inputs is a list, the ith element of which is a list of
 	vectors and/or scalars that are suitable for use as the ith
@@ -805,34 +937,73 @@ def _make_vector_or_matrix_test_vectors(test_suite_dict):
 	If tolerance_function is supplied, it is a function which
 	should be used to compute the tolerance for the test vectors.
 	Otherwise, _strict_tolerance is used.
+
+	If template is supplied, it is used insted as the template for
+	the Signature objects generated.
 	"""
 	test_inputs = make_arguments(test_inputs)
-	if argument_indices_to_match is not None:
+	if filter is not None:
 	    test_inputs = [
 		arguments
 		for arguments in test_inputs
-		if _argument_types_match(arguments, argument_indices_to_match)]
+		if filter(*arguments)]
 	_store_test_vectors(
 	    test_suite_dict, name, glsl_version,
 	    _simulate_function(
-		test_inputs, python_equivalent, tolerance_function))
-    f('length', 1, '1.10', np.linalg.norm, None, [_std_vectors])
-    f('distance', 2, '1.10', lambda x, y: np.linalg.norm(x-y), [0, 1], [_std_vectors, _std_vectors])
-    f('dot', 2, '1.10', np.dot, [0, 1], [_std_vectors, _std_vectors])
-    f('cross', 2, '1.10', np.cross, [0, 1], [_std_vectors3, _std_vectors3], _cross_product_tolerance)
-    f('normalize', 1, '1.10', _normalize, None, [_std_vectors])
-    f('faceforward', 3, '1.10', _faceforward, [0, 1, 2], [_std_vectors, _std_vectors, _std_vectors])
-    f('reflect', 2, '1.10', _reflect, [0, 1], [_std_vectors, _normalized_vectors])
-    f('refract', 3, '1.10', _refract, [0, 1], [_normalized_vectors, _normalized_vectors, [0.5, 2.0]])
+		test_inputs, python_equivalent, tolerance_function),
+	    template = template)
+    f('op-add', 2, '1.10', lambda x, y: x + y, match_simple_binop, [floats+vecs+mats+ints+ivecs, floats+vecs+mats+ints+ivecs], template = '({0} + {1})')
+    f('op-sub', 2, '1.10', lambda x, y: x - y, match_simple_binop, [floats+vecs+mats+ints+ivecs, floats+vecs+mats+ints+ivecs], template = '({0} - {1})')
+    f('op-mult', 2, '1.10', _multiply, match_multiply, [floats+vecs+mats+ints+ivecs, floats+vecs+mats+ints+ivecs], template = '({0} * {1})')
+    f('op-div', 2, '1.10', _divide, match_simple_binop, [floats+vecs+mats+ints+ivecs, floats+vecs+mats+ints+ivecs], template = '({0} / {1})')
+    f('op-uplus', 1, '1.10', lambda x: +x, None, [floats+vecs+mats+ints+ivecs], template = '(+ {0})')
+    f('op-neg', 1, '1.10', lambda x: -x, None, [floats+vecs+mats+ints+ivecs], template = '(- {0})')
+    f('op-gt', 2, '1.10', lambda x, y: x > y, match_args(0, 1), [ints+floats, ints+floats], template = '({0} > {1})')
+    f('op-lt', 2, '1.10', lambda x, y: x < y, match_args(0, 1), [ints+floats, ints+floats], template = '({0} < {1})')
+    f('op-ge', 2, '1.10', lambda x, y: x >= y, match_args(0, 1), [ints+floats, ints+floats], template = '({0} >= {1})')
+    f('op-le', 2, '1.10', lambda x, y: x <= y, match_args(0, 1), [ints+floats, ints+floats], template = '({0} <= {1})')
+    f('op-eq', 2, '1.10', _equal, match_args(0, 1), [floats+vecs+mats+ints+ivecs+bools+bvecs, floats+vecs+mats+ints+ivecs+bools+bvecs], template = '({0} == {1})')
+    f('op-ne', 2, '1.10', _not_equal, match_args(0, 1), [floats+vecs+mats+ints+ivecs+bools+bvecs, floats+vecs+mats+ints+ivecs+bools+bvecs], template = '({0} != {1})')
+    f('op-and', 2, '1.10', lambda x, y: x and y, None, [bools, bools], template = '({0} && {1})')
+    f('op-or', 2, '1.10', lambda x, y: x or y, None, [bools, bools], template = '({0} || {1})')
+    f('op-xor', 2, '1.10', lambda x, y: x != y, None, [bools, bools], template = '({0} ^^ {1})')
+    f('op-not', 1, '1.10', lambda x: not x, None, [bools], template = '(! {0})')
+    f('op-selection', 3, '1.10', lambda x, y, z: y if x else z, match_args(1, 2), [bools, floats+vecs+mats+ints+ivecs+bools+bvecs, floats+vecs+mats+ints+ivecs+bools+bvecs], template = '({0} ? {1} : {2})')
+    f('length', 1, '1.10', np.linalg.norm, None, [floats+vecs])
+    f('distance', 2, '1.10', lambda x, y: np.linalg.norm(x-y), match_args(0, 1), [floats+vecs, floats+vecs])
+    f('dot', 2, '1.10', np.dot, match_args(0, 1), [floats+vecs, floats+vecs])
+    f('cross', 2, '1.10', np.cross, match_args(0, 1), [vec3s, vec3s], _cross_product_tolerance)
+    f('normalize', 1, '1.10', _normalize, None, [nz_floats_vecs])
+    f('faceforward', 3, '1.10', _faceforward, match_args(0, 1, 2), [floats+vecs, floats+vecs, floats+vecs])
+    f('reflect', 2, '1.10', _reflect, match_args(0, 1), [floats+vecs, norm_floats_vecs])
+    f('refract', 3, '1.10', _refract, match_args(0, 1), [norm_floats_vecs, norm_floats_vecs, [0.5, 2.0]])
 
     # Note: technically matrixCompMult operates componentwise.
     # However, since it is the only componentwise function to operate
     # on matrices, it is easier to generate test cases for it here
     # than to add matrix support to _make_componentwise_test_vectors.
-    f('matrixCompMult', 2, '1.10', lambda x, y: x*y, [0, 1], [_std_matrices, _std_matrices])
+    f('matrixCompMult', 2, '1.10', lambda x, y: x*y, match_args(0, 1), [mats, mats])
 
-    f('outerProduct', 2, '1.20', np.outer, None, [_nontrivial_vectors, _nontrivial_vectors])
-    f('transpose', 1, '1.20', np.transpose, None, [_std_matrices])
-    f('any', 1, '1.10', any, None, [_bvecs])
-    f('all', 1, '1.10', all, None, [_bvecs])
+    f('outerProduct', 2, '1.20', np.outer, None, [vecs, vecs])
+    f('transpose', 1, '1.20', np.transpose, None, [mats])
+    f('any', 1, '1.10', any, None, [bvecs])
+    f('all', 1, '1.10', all, None, [bvecs])
 _make_vector_or_matrix_test_vectors(test_suite)
+
+
+
+def _check_signature_safety(test_suite_dict):
+    """As a final safety check, verify that for each possible
+    combination of name and argtypes, there is exactly one
+    signature.
+    """
+    name_argtype_combos = set()
+    for signature in test_suite_dict:
+	name_argtype_combo = (signature.name, signature.argtypes)
+	if name_argtype_combo in name_argtype_combos:
+	    raise Exception(
+		'Duplicate signature found for {0}'.format(name_argtype_combo))
+	name_argtype_combos.add(name_argtype_combo)
+    for x in sorted(name_argtype_combos):
+	print x
+_check_signature_safety(test_suite)
diff --git a/generated_tests/gen_builtin_uniform_tests.py b/generated_tests/gen_builtin_uniform_tests.py
index 64cb927..752cfb7 100644
--- a/generated_tests/gen_builtin_uniform_tests.py
+++ b/generated_tests/gen_builtin_uniform_tests.py
@@ -158,6 +158,29 @@ class BoolComparator(Comparator):
 
 
 
+class IntComparator(Comparator):
+    def __init__(self, signature):
+	self.__signature = signature
+
+    def make_additional_declarations(self):
+	return 'uniform {0} expected;\n'.format(self.__signature.rettype)
+
+    def make_result_handler(self, output_var):
+	return '  {v} = {cond} ? {green} : {red};\n'.format(
+	    v=output_var, cond='result == expected',
+	    green='vec4(0.0, 1.0, 0.0, 1.0)',
+	    red='vec4(1.0, 0.0, 0.0, 1.0)')
+
+    def make_result_test(self, test_num, test_vector):
+	test = 'uniform {0} expected {1}\n'.format(
+	    shader_runner_type(self.__signature.rettype),
+	    shader_runner_format(column_major_values(test_vector.result)))
+	test += 'draw rect -1 -1 2 2\n'
+	test += 'probe rgba {0} 0 0.0 1.0 0.0 1.0\n'.format(test_num)
+	return test
+
+
+
 class FloatComparator(Comparator):
     def __init__(self, signature):
 	self.__signature = signature
@@ -239,6 +262,8 @@ class ShaderTest(object):
 	    self._comparator = BoolComparator(signature)
 	elif signature.rettype.base_type == glsl_float:
 	    self._comparator = FloatComparator(signature)
+	elif signature.rettype.base_type == glsl_int:
+	    self._comparator = IntComparator(signature)
 	else:
 	    raise Exception('Unexpected rettype {0}'.format(signature.rettype))
 
@@ -288,10 +313,11 @@ class ShaderTest(object):
 	shader += 'void main()\n'
 	shader += '{\n'
 	shader += additional_statements
-	args = ', '.join(
-	    'arg{0}'.format(i) for i in xrange(len(self._signature.argtypes)))
-	shader += '  {0} result = {1}({2});\n'.format(
-		self._signature.rettype, self._signature.name, args)
+	invocation = self._signature.template.format(
+	    *['arg{0}'.format(i)
+	      for i in xrange(len(self._signature.argtypes))])
+	shader += '  {0} result = {1};\n'.format(
+		self._signature.rettype, invocation)
 	shader += self._comparator.make_result_handler(output_var)
 	shader += '}\n'
 	return shader
@@ -307,7 +333,10 @@ class ShaderTest(object):
 		    shader_runner_type(self._signature.argtypes[i]),
 		    i, shader_runner_format(
 			column_major_values(test_vector.arguments[i])))
-	    test += self._comparator.make_result_test(test_num, test_vector)
+	    # 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)
 	return test
 
     def filename(self):
diff --git a/generated_tests/gen_constant_array_size_tests.py b/generated_tests/gen_constant_array_size_tests.py
index 8258866..5a54e00 100644
--- a/generated_tests/gen_constant_array_size_tests.py
+++ b/generated_tests/gen_constant_array_size_tests.py
@@ -84,16 +84,15 @@ class ParserTest(object):
 	true if the GLSL compiler's constant evaluation produces the
 	correct result for the given test vector, and false if not.
 	"""
-	funcall = '{0}({1})'.format(
-	    self.__signature.name, ', '.join(
-		glsl_constant(x) for x in test_vector.arguments))
+	invocation = self.__signature.template.format(
+	    *[glsl_constant(x) for x in test_vector.arguments])
 	if self.__signature.rettype.base_type == glsl_float:
 	    # Test floating-point values within tolerance
 	    if self.__signature.name == 'distance':
 		# Don't use the distance() function to test itself.
 		return '{0} <= {1} && {1} <= {2}'.format(
 		    test_vector.result - test_vector.tolerance,
-		    funcall,
+		    invocation,
 		    test_vector.result + test_vector.tolerance)
 	    elif self.__signature.rettype.is_matrix:
 		# We can't apply distance() to matrices.  So apply it
@@ -103,7 +102,7 @@ class ParserTest(object):
 		terms = []
 		for col in xrange(self.__signature.rettype.num_cols):
 		    terms.append('pow(distance({0}[{1}], {2}), 2)'.format(
-			    funcall, col,
+			    invocation, col,
 			    glsl_constant(test_vector.result[:,col])))
 		rss_distance = ' + '.join(terms)
 		sq_tolerance = test_vector.tolerance * test_vector.tolerance
@@ -111,7 +110,7 @@ class ParserTest(object):
 		    rss_distance, glsl_constant(sq_tolerance))
 	    else:
 		return 'distance({0}, {1}) <= {2}'.format(
-		    funcall, glsl_constant(test_vector.result),
+		    invocation, glsl_constant(test_vector.result),
 		    glsl_constant(test_vector.tolerance))
 	else:
 	    # Test non-floating point values exactly
@@ -122,15 +121,15 @@ class ParserTest(object):
 		terms = []
 		for row in xrange(self.__signature.rettype.num_rows):
 		    terms.append('{0}[{1}] == {2}'.format(
-			    funcall, row,
+			    invocation, row,
 			    glsl_constant(test_vector.result[row])))
 		return ' && '.join(terms)
 	    elif self.__signature.rettype.is_vector:
 		return 'all(equal({0}, {1}))'.format(
-		    funcall, glsl_constant(test_vector.result))
+		    invocation, glsl_constant(test_vector.result))
 	    else:
 		return '{0} == {1}'.format(
-		    funcall, glsl_constant(test_vector.result))
+		    invocation, glsl_constant(test_vector.result))
 
     def make_shader(self):
 	"""Generate the shader code necessary to test the built-in."""
@@ -166,9 +165,9 @@ class ParserTest(object):
 	parser_test += ' *\n'
 	parser_test += ' * Check that the following test vectors are constant folded correctly:\n'
 	for test_vector in self.__test_vectors:
-	    parser_test += ' * {0}({1}) => {2}\n'.format(
-		self.__signature.name,
-		', '.join(glsl_constant(arg) for arg in test_vector.arguments),
+	    parser_test += ' * {0} => {1}\n'.format(
+		self.__signature.template.format(
+		    *[glsl_constant(arg) for arg in test_vector.arguments]),
 		glsl_constant(test_vector.result))
 	parser_test += ' */\n'
 	parser_test += self.make_shader()
-- 
1.7.6



More information about the Piglit mailing list