3 # Copyright © 2011 Intel Corporation
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 # and/or sell copies of the Software, and to permit persons to whom the
10 # Software is furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 # DEALINGS IN THE SOFTWARE.
24 # This source file defines a set of test vectors that can be used to
25 # test GLSL's built-in functions and operators. It is intended to be
26 # used by Python code that generates Piglit tests.
28 # The key export is the dictionary test_suite. It contains an entry
29 # for each possible overload of every pure built-in function and
30 # operator. By iterating through this dictionary you can find a set
31 # of test vectors for testing nearly every built-in GLSL function.
33 # The following functions are not included, since they are not pure,
34 # so they can't be tested using simple vectors:
39 # - Increment and decrement operators
41 # The following functions are not included, since they need to be
42 # tested in specialized ways:
43 # - modf(): not tested because it has an out parameter
44 # - isnan() and isinf(): not tested because special effort is required
45 # to create values that cause these functions to return true.
47 # Also not tested are array subscripting, field/method selection,
48 # swizzling, the function call operator, assignment, and the sequence
59 # Floating point types used by Python and numpy
60 FLOATING_TYPES
= (float, np
.float64
, np
.float32
)
62 # Due to a bug in the Windows implementation of numpy, there are
63 # multiple int32 types (and multiple uint32 types). So we have to
64 # find them all when doing isinstance checks. The following code will
65 # create two-element tuples on numpy implementations that have the
66 # bug, and one-element tuples on numpy implementations that don't.
67 INT32_TYPES
= tuple(set([np
.int32
, type(np
.abs(np
.int32(1)))]))
68 UINT32_TYPES
= tuple(set([np
.uint32
,
69 type(np
.dot(np
.uint32(0), np
.uint32(0)))]))
72 @functools.total_ordering
73 class GlslBuiltinType(object):
74 """Class representing a GLSL built-in type."""
75 def __init__(self
, name
, base_type
, num_cols
, num_rows
,
78 if base_type
is not None:
79 self
.__base
_type
= base_type
81 self
.__base
_type
= self
82 self
.__num
_cols
= num_cols
83 self
.__num
_rows
= num_rows
84 self
.__version
_introduced
= version_introduced
88 """The name of the type, as a string."""
93 """For vectors and matrices, the type of data stored in each
94 element. For scalars, equal to self.
96 return self
.__base
_type
100 """For matrices, the number of columns. For vectors and
103 return self
.__num
_cols
107 """For vectors and matrices, the number of rows. For scalars,
110 return self
.__num
_rows
114 return self
.__num
_cols
== 1 and self
.__num
_rows
== 1
118 return self
.__num
_cols
== 1 and self
.__num
_rows
!= 1
122 return self
.__num
_cols
!= 1
125 def version_introduced(self
):
126 """The earliest version of GLSL that this type appears in (as
129 return self
.__version
_introduced
131 def __eq__(self
, other
):
132 if isinstance(other
, GlslBuiltinType
):
133 return self
.name
== other
.name
135 return NotImplemented
137 def __lt__(self
, other
):
138 if isinstance(other
, GlslBuiltinType
):
139 return self
.name
< other
.name
141 return NotImplemented
144 return hash('__GLslBuiltinType_{}__'.format(self
.name
))
150 return 'glsl_{0}'.format(self
.__name
)
153 # Concrete declarations of GlslBuiltinType
154 glsl_bool
= GlslBuiltinType('bool', None, 1, 1, 110)
155 glsl_int
= GlslBuiltinType('int', None, 1, 1, 110)
156 glsl_uint
= GlslBuiltinType('uint', None, 1, 1, 130)
157 glsl_float
= GlslBuiltinType('float', None, 1, 1, 110)
158 glsl_vec2
= GlslBuiltinType('vec2', glsl_float
, 1, 2, 110)
159 glsl_vec3
= GlslBuiltinType('vec3', glsl_float
, 1, 3, 110)
160 glsl_vec4
= GlslBuiltinType('vec4', glsl_float
, 1, 4, 110)
161 glsl_bvec2
= GlslBuiltinType('bvec2', glsl_bool
, 1, 2, 110)
162 glsl_bvec3
= GlslBuiltinType('bvec3', glsl_bool
, 1, 3, 110)
163 glsl_bvec4
= GlslBuiltinType('bvec4', glsl_bool
, 1, 4, 110)
164 glsl_ivec2
= GlslBuiltinType('ivec2', glsl_int
, 1, 2, 110)
165 glsl_ivec3
= GlslBuiltinType('ivec3', glsl_int
, 1, 3, 110)
166 glsl_ivec4
= GlslBuiltinType('ivec4', glsl_int
, 1, 4, 110)
167 glsl_uvec2
= GlslBuiltinType('uvec2', glsl_uint
, 1, 2, 130)
168 glsl_uvec3
= GlslBuiltinType('uvec3', glsl_uint
, 1, 3, 130)
169 glsl_uvec4
= GlslBuiltinType('uvec4', glsl_uint
, 1, 4, 130)
170 glsl_mat2
= GlslBuiltinType('mat2', glsl_float
, 2, 2, 110)
171 glsl_mat3
= GlslBuiltinType('mat3', glsl_float
, 3, 3, 110)
172 glsl_mat4
= GlslBuiltinType('mat4', glsl_float
, 4, 4, 110)
173 glsl_mat2x2
= glsl_mat2
174 glsl_mat3x2
= GlslBuiltinType('mat3x2', glsl_float
, 3, 2, 120)
175 glsl_mat4x2
= GlslBuiltinType('mat4x2', glsl_float
, 4, 2, 120)
176 glsl_mat2x3
= GlslBuiltinType('mat2x3', glsl_float
, 2, 3, 120)
177 glsl_mat3x3
= glsl_mat3
178 glsl_mat4x3
= GlslBuiltinType('mat4x3', glsl_float
, 4, 3, 120)
179 glsl_mat2x4
= GlslBuiltinType('mat2x4', glsl_float
, 2, 4, 120)
180 glsl_mat3x4
= GlslBuiltinType('mat3x4', glsl_float
, 3, 4, 120)
181 glsl_mat4x4
= glsl_mat4
182 glsl_int64_t
= GlslBuiltinType('int64_t', None, 1, 1, 400)
183 glsl_i64vec2
= GlslBuiltinType('i64vec2', glsl_int64_t
, 1, 2, 400)
184 glsl_i64vec3
= GlslBuiltinType('i64vec3', glsl_int64_t
, 1, 3, 400)
185 glsl_i64vec4
= GlslBuiltinType('i64vec4', glsl_int64_t
, 1, 4, 400)
186 glsl_uint64_t
= GlslBuiltinType('uint64_t', None, 1, 1, 400)
187 glsl_u64vec2
= GlslBuiltinType('u64vec2', glsl_uint64_t
, 1, 2, 400)
188 glsl_u64vec3
= GlslBuiltinType('u64vec3', glsl_uint64_t
, 1, 3, 400)
189 glsl_u64vec4
= GlslBuiltinType('u64vec4', glsl_uint64_t
, 1, 4, 400)
191 # Named tuple representing the signature of a single overload of a
192 # built-in GLSL function or operator:
193 # - name is a name suitable for use in test filenames. For functions,
194 # this is the name of the function. For operators, it is a short
195 # description of the operator, beginning with "op", e.g. "op-plus".
196 # - template is a Python format string that can be used to construct
197 # GLSL code that invokes the function or operator.
198 # - version_introduced earliest version of GLSL the test applies to
199 # (as a string, e.g. 110).
200 # - rettype is the return type of the function or operator (as a
202 # - argtypes is a tuple containing the types of each parameter (as
205 # For example, the function
207 # vec3 step(float edge, vec3 x)
211 # Signature(name='step', template='step({0}, {1})',
212 # version_introduced=110, rettype='vec3',
213 # argtypes=('float', 'vec3'))
214 Signature
= collections
.namedtuple(
216 ('name', 'template', 'version_introduced', 'extension', 'rettype', 'argtypes'))
219 # Named tuple representing a single piece of test data for testing a
220 # built-in GLSL function:
221 # - arguments is a tuple containing the arguments to apply to the
222 # function. Each argument is of a type native to numpy (e.g.
223 # numpy.float32 or numpy.ndarray)
224 # - result is the value the function is expected to return. It is
225 # also of a type native to numpy.
226 # - tolerance is a float32 representing how much deviation from the
227 # result we expect, considering the floating point precision
228 # requirements of GLSL and OpenGL. The value may be zero for test
229 # vectors involving booleans and integers. If result is a vector or
230 # matrix, tolerance should be interpreted as the maximum permissible
231 # RMS error (as would be computed by the distance() function).
232 TestVector
= collections
.namedtuple(
233 'TestVector', ('arguments', 'result', 'tolerance'))
236 def glsl_type_of(value
):
237 """Return the GLSL type corresponding to the given native numpy
238 value, as a GlslBuiltinType.
240 if isinstance(value
, FLOATING_TYPES
):
242 elif isinstance(value
, (bool, np
.bool_
)):
244 elif isinstance(value
, INT32_TYPES
):
246 elif isinstance(value
, UINT32_TYPES
):
248 elif isinstance(value
, np
.int64
):
250 elif isinstance(value
, np
.uint64
):
253 assert isinstance(value
, np
.ndarray
)
254 if len(value
.shape
) == 1:
256 vector_length
= value
.shape
[0]
257 assert 2 <= vector_length
<= 4
258 if value
.dtype
in FLOATING_TYPES
:
259 return (glsl_vec2
, glsl_vec3
, glsl_vec4
)[vector_length
- 2]
260 elif value
.dtype
== np
.int64
:
261 return (glsl_i64vec2
, glsl_i64vec3
, glsl_i64vec4
)[vector_length
- 2]
262 elif value
.dtype
== np
.uint64
:
263 return (glsl_u64vec2
, glsl_u64vec3
, glsl_u64vec4
)[vector_length
- 2]
264 elif value
.dtype
== bool:
265 return (glsl_bvec2
, glsl_bvec3
, glsl_bvec4
)[vector_length
- 2]
266 elif value
.dtype
in INT32_TYPES
:
267 return (glsl_ivec2
, glsl_ivec3
, glsl_ivec4
)[vector_length
- 2]
268 elif value
.dtype
in UINT32_TYPES
:
269 return (glsl_uvec2
, glsl_uvec3
, glsl_uvec4
)[vector_length
- 2]
272 'Unexpected vector base type {0}'.format(value
.dtype
))
275 assert value
.dtype
in FLOATING_TYPES
276 assert len(value
.shape
) == 2
277 matrix_rows
= value
.shape
[0]
278 assert 2 <= matrix_rows
<= 4
279 matrix_columns
= value
.shape
[1]
280 assert 2 <= matrix_columns
<= 4
281 matrix_types
= ((glsl_mat2x2
, glsl_mat2x3
, glsl_mat2x4
),
282 (glsl_mat3x2
, glsl_mat3x3
, glsl_mat3x4
),
283 (glsl_mat4x2
, glsl_mat4x3
, glsl_mat4x4
))
284 return matrix_types
[matrix_columns
- 2][matrix_rows
- 2]
287 def column_major_values(value
):
288 """Given a native numpy value, return a list of the scalar values
289 comprising it, in column-major order."""
290 if isinstance(value
, np
.ndarray
):
291 return list(np
.reshape(value
, -1, 'F'))
296 def glsl_constant(value
):
297 """Given a native numpy value, return GLSL code that constructs
299 column_major
= np
.reshape(np
.array(value
), -1, 'F')
300 if column_major
.dtype
== bool:
301 values
= ['true' if x
else 'false' for x
in column_major
]
302 elif column_major
.dtype
== np
.int64
:
303 values
= [repr(x
) + 'l' for x
in column_major
]
304 elif column_major
.dtype
== np
.uint64
:
305 values
= [repr(x
) + 'ul' for x
in column_major
]
306 elif column_major
.dtype
in UINT32_TYPES
:
307 values
= [repr(x
) + 'u' for x
in column_major
]
309 values
= [repr(x
) for x
in column_major
]
310 if len(column_major
) == 1:
313 return '{0}({1})'.format(glsl_type_of(value
), ', '.join(values
))
316 def round_to_32_bits(value
):
317 """If value is a floating point type, round it down to 32 bits.
318 Otherwise return it unchanged.
320 if isinstance(value
, float):
321 return np
.float32(value
)
322 elif isinstance(value
, np
.ndarray
) and value
.dtype
== np
.float64
:
323 return np
.array(value
, dtype
=np
.float32
)
328 def extend_to_64_bits(value
):
329 """If value is a floating point type, extend it to 64 bits.
330 Otherwise return it unchanged.
332 if isinstance(value
, np
.float32
):
333 return np
.float64(value
)
334 elif isinstance(value
, np
.ndarray
) and value
.dtype
== np
.float32
:
335 return np
.array(value
, dtype
=np
.float64
)
340 # Dictionary containing the test vectors. Each entry in the
341 # dictionary represents a single overload of a single built-in
342 # function. Its key is a Signature tuple, and its value is a list of
345 # Note: the dictionary is initialized to {} here, but it is filled
346 # with test vectors by code later in this file.
353 # The functions below shouldn't be necessary to call from outside this
354 # file. They exist solely to populate test_suite with test vectors.
356 # Functions that simulate GLSL built-in functions (in the cases where
357 # the GLSL built-in functions have no python or numpy equivalent, or
358 # in cases where there is a behavioral difference). These functions
359 # return None if the behavior of the GLSL built-in is undefined for
360 # the given set of inputs.
362 x_type
= glsl_type_of(x
)
363 y_type
= glsl_type_of(y
)
365 if x_type
.is_vector
and y_type
.is_vector
:
366 # vector * vector is done componentwise.
369 # All other cases are standard linear algebraic
370 # multiplication, which numpy calls "dot".
375 if any(y_element
== 0 for y_element
in column_major_values(y
)):
376 # Division by zero is undefined.
378 if glsl_type_of(x
).base_type
== glsl_int
or glsl_type_of(x
).base_type
== glsl_int64_t
:
379 # The GLSL spec does not make it clear what the rounding rules
380 # are when performing integer division. C99 requires
381 # round-toward-zero, so in the absence of any other
382 # information, assume that's the correct behavior for GLSL.
384 # Python and numpy's rounding rules are inconsistent, so to
385 # make sure we get round-toward-zero behavior, divide the
386 # absolute values of x and y, and then fix the sign.
387 return (np
.abs(x
) // np
.abs(y
)) * (np
.sign(x
) * np
.sign(y
))
388 elif glsl_type_of(x
).base_type
== glsl_uint
or glsl_type_of(x
).base_type
== glsl_uint64_t
:
395 if any(x_element
< 0 for x_element
in column_major_values(x
)):
396 # Modulus operation with a negative first operand is
399 if any(y_element
<= 0 for y_element
in column_major_values(y
)):
400 # Modulus operation with a negative or zero second operand is
407 base
= glsl_type_of(x
).base_type
408 if base
in (glsl_int64_t
, glsl_uint64_t
):
410 shift_type
= glsl_int
if base
== glsl_int64_t
else glsl_uint
414 if not all(0 <= y_element
< bits
for y_element
in column_major_values(y
)):
415 # Shifts by less than 0 or more than the number of bits in the
416 # type being shifted are undefined.
418 # When the arguments to << don't have the same signedness, numpy
419 # likes to promote them to int64. To avoid this, convert y to be
420 # the same type as x.
422 if glsl_type_of(y
).base_type
!= shift_type
:
423 y
= _change_signedness(y
)
426 # Shifting should always produce a result with the same base type
427 # as the left argument.
428 assert glsl_type_of(result
).base_type
== glsl_type_of(x
).base_type
434 base
= glsl_type_of(x
).base_type
435 if base
in (glsl_int64_t
, glsl_uint64_t
):
437 shift_type
= glsl_int
if base
== glsl_int64_t
else glsl_uint
441 if not all(0 <= y_element
< bits
for y_element
in column_major_values(y
)):
442 # Shifts by less than 0 or more than the number of bits in the
443 # type being shifted are undefined.
445 # When the arguments to >> don't have the same signedness, numpy
446 # likes to promote them to int64. To avoid this, convert y to be
447 # the same type as x.
449 if glsl_type_of(y
).base_type
!= shift_type
:
450 y
= _change_signedness(y
)
453 # Shifting should always produce a result with the same base type
454 # as the left argument.
455 assert glsl_type_of(result
).base_type
== glsl_type_of(x
).base_type
461 return all(column_major_values(x
== y
))
464 def _not_equal(x
, y
):
465 return not _equal(x
, y
)
471 return np
.arctan2(y
, x
)
477 if x
== 0.0 and y
<= 0.0:
479 return np
.power(x
, y
)
483 # exp2() is not available in versions of numpy < 1.3.0 so we
484 # emulate it with power().
485 return np
.power(2, x
)
489 # trunc() rounds toward zero. It is not available in version
490 # 1.2.1 of numpy so we emulate it with floor(), sign(), and abs().
491 return np
.sign(x
) * np
.floor(np
.abs(x
))
494 def _clamp(x
, minVal
, maxVal
):
497 return min(max(x
, minVal
), maxVal
)
500 # Inefficient, but obvious
502 return np
.sort([x
, y
, z
])[1]
504 def _smoothstep(edge0
, edge1
, x
):
507 t
= _clamp((x
-edge0
)/(edge1
-edge0
), 0.0, 1.0)
508 return t
*t
*(3.0-2.0*t
)
512 return x
/np
.linalg
.norm(x
)
515 def _faceforward(N
, I
, Nref
):
516 if np
.dot(Nref
, I
) < 0.0:
523 return I
-2*np
.dot(N
, I
)*N
526 def _refract(I
, N
, eta
):
527 k
= 1.0-eta
*eta
*(1.0-np
.dot(N
, I
)*np
.dot(N
, I
))
531 return eta
*I
-(eta
*np
.dot(N
, I
)+np
.sqrt(k
))*N
534 def _change_signedness(x
):
535 """Change signed integer types to unsigned integer types and vice
537 if isinstance(x
, INT32_TYPES
):
539 elif isinstance(x
, UINT32_TYPES
):
541 elif isinstance(x
, np
.ndarray
):
542 if (x
.dtype
in INT32_TYPES
):
543 return np
.array(x
, dtype
=np
.uint32
)
544 elif (x
.dtype
in UINT32_TYPES
):
545 return np
.array(x
, dtype
=np
.int32
)
546 raise Exception('Unexpected type passed to _change_signedness')
549 def _argument_types_match(arguments
, argument_indices_to_match
):
550 """Return True if all of the arguments indexed by
551 argument_indices_to_match have the same GLSL type.
553 types
= [glsl_type_of(arguments
[i
]) for i
in argument_indices_to_match
]
554 return all(x
== types
[0] for x
in types
)
557 def _strict_tolerance(arguments
, result
):
558 """Compute tolerance using a strict interpretation of the GLSL and
561 From the GLSL 1.20 spec (4.1.4 "Floats"):
563 "As an input value to one of the processing units, a
564 floating-point variable is expected to match the IEEE single
565 precision floating-point definition for precision and dynamic
566 range. It is not required that the precision of internal
567 processing match the IEEE floating-point specification for
568 floating-point operations, but the guidelines for precision
569 established by the OpenGL 1.4 specification must be met."
571 From the OpenGL 1.4 spec (2.1.1 "Floating-Point Computation"):
573 "We require simply that numbers' floating-point parts contain
574 enough bits ... so that individual results of floating-point
575 operations are accurate to about 1 part in 10^5."
577 A harsh interpretation of the above is that (a) no precision is
578 lost in moving numbers into or out of the GPU, and (b) any
579 built-in function constitutes a single operation, so therefore the
580 error in applying any built-in function should be off by no more
581 than 1e-5 times its theoretically correct value.
583 This is not the only possible interpretation, however. Certain
584 built-in functions, such as the cross product, are computed by a
585 formula consisting of many elementary multiplications and
586 additions, in which a large amount of cancellation sometimes
587 occurs. It's possible that these rules are meant to apply to
588 those elementary multiplications and additions, and not the full
589 built-in function. Other built-in functions, such as the trig
590 functions, are typically implemented by a series approximation, in
591 which 1 part in 10^5 accuracy seems like overkill. See below for
592 the tolerance computation we use on these other functions.
594 return 1e-5 * np
.linalg
.norm(result
)
597 def _trig_tolerance(arguments
, result
):
598 """Compute a more lenient tolerance bound for trig functions.
600 The GLSL and OpenGL specs don't provide any guidance as to the
601 required accuracy of trig functions (other than the "1 part in
602 10^5" general accuracy requirement, which seems like overkill for
605 So the tolerance here is rather arbitrarily chosen to be either 1
606 part in 10^3 or 10^-4, whichever is larger.
608 return max(1e-4, 1e-3 * np
.linalg
.norm(result
))
611 def _cross_product_tolerance(arguments
, result
):
612 """Compute a more lenient tolerance bound for cross product.
614 Since the computation of a cross product may involve a large
615 amount of cancellation, an error tolerance of 1 part in 10^5
616 (referred to the magnitude of the result vector) is overly tight.
618 So instead we allow the error to be 1 part in 10^5 referred to the
619 product of the magnitudes of the arguments.
621 assert len(arguments
) == 2
622 return 1e-5 * np
.linalg
.norm(arguments
[0]) * np
.linalg
.norm(arguments
[1])
625 def _simulate_function(test_inputs
, python_equivalent
, tolerance_function
):
626 """Construct test vectors by simulating a GLSL function on a list
627 of possible inputs, and return a list of test vectors.
629 test_inputs is a list of possible input sequences, each of which
630 represents a set of arguments that should be applied to the
633 python_equivalent is the function to simulate--it should return
634 None if the GLSL function returns undefined results for the given
635 set of inputs, otherwise it should return the expected result.
636 Input sequences for which python_equivalent returns None are
639 tolerance_function is the function to call to compute the
640 tolerance. It should take the set of arguments and the expected
641 result as its parameters. It is only used for functions that
642 return floating point values.
644 python_equivalent and tolerance_function are simulated using 64
645 bit floats for maximum possible accuracy. The vector, however, is
646 built with rounded to 32 bits values since that is the data type
647 that we expect to get back from OpenGL.
650 for inputs
in test_inputs
:
651 expected_output
= python_equivalent(
652 *[extend_to_64_bits(x
) for x
in inputs
])
653 if expected_output
is not None:
654 if glsl_type_of(expected_output
).base_type
!= glsl_float
:
657 tolerance
= tolerance_function(inputs
, expected_output
)
658 test_vectors
.append(TestVector(inputs
,
659 round_to_32_bits(expected_output
),
660 round_to_32_bits(tolerance
)))
664 def _vectorize_test_vectors(test_vectors
, scalar_arg_indices
, vector_length
):
665 """Build a new set of test vectors by combining elements of
666 test_vectors into vectors of length vector_length. For example,
667 vectorizing the test vectors
669 [TestVector((10, 20), 30, tolerance), TestVector((11, 20), 31, tolerance)]
671 into vectors of length 2 would produce the result:
673 [TestVector((vec2(10, 11), vec2(20, 20)), vec2(30, 31), new_tolerance)].
675 Tolerances are combined in root-sum-square fashion.
677 scalar_arg_indices is a sequence of argument indices which should
678 not be vectorized. So, if scalar_arg_indices is [1] in the above
679 example, the result would be:
681 [TestVector((vec2(10, 11), 20), vec2(30, 31), new_tolerance)].
683 def make_groups(test_vectors
):
684 """Group test vectors according to the values passed to the
685 arguments that should not be vectorized.
688 for tv
in test_vectors
:
689 key
= tuple(tv
.arguments
[i
] for i
in scalar_arg_indices
)
690 if key
not in groups
:
692 groups
[key
].append(tv
)
695 def partition_vectors(test_vectors
, partition_size
):
696 """Partition test_vectors into lists of length partition_size.
697 If partition_size does not evenly divide the number of test
698 vectors, wrap around as necessary to ensure that every input
699 test vector is included.
701 for i
in range(0, len(test_vectors
), partition_size
):
703 for j
in range(partition_size
):
704 partition
.append(test_vectors
[(i
+ j
) % len(test_vectors
)])
707 def merge_vectors(test_vectors
):
708 """Merge the given set of test vectors (whose arguments and
709 result are scalars) into a single test vector whose arguments
710 and result are vectors. For argument indices in
711 scalar_arg_indices, leave the argument as a scalar.
713 arity
= len(test_vectors
[0].arguments
)
715 for j
in range(arity
):
716 if j
in scalar_arg_indices
:
717 arguments
.append(test_vectors
[0].arguments
[j
])
720 np
.array([tv
.arguments
[j
] for tv
in test_vectors
]))
721 result
= np
.array([tv
.result
for tv
in test_vectors
])
722 tolerance
= np
.linalg
.norm(
723 [tv
.tolerance
for tv
in test_vectors
])
724 return TestVector(arguments
, result
, tolerance
)
726 vectorized_test_vectors
= []
727 groups
= make_groups(test_vectors
)
728 for key
in sorted(groups
.keys()):
729 test_vectors
= groups
[key
]
730 vectorized_test_vectors
.extend(
731 merge_vectors(partition
)
732 for partition
in partition_vectors(test_vectors
, vector_length
))
733 return vectorized_test_vectors
736 def _store_test_vector(test_suite_dict
, name
, glsl_version
, extension
, test_vector
,
738 """Store a test vector in the appropriate place in
739 test_suite_dict. The dictionary key (which is a Signature tuple)
740 is generated by consulting the argument and return types of the
741 test vector, and combining them with name and glsl_version.
743 glsl_version is adjusted if necessary to reflect when the argument
744 and return types were introduced into GLSL.
746 If template is supplied, it is used insted as the template for the
747 Signature objects generated.
750 arg_indices
= range(len(test_vector
.arguments
))
751 template
= '{0}({1})'.format(
752 name
, ', '.join('{{{0}}}'.format(i
) for i
in arg_indices
))
753 rettype
= glsl_type_of(test_vector
.result
)
754 argtypes
= tuple(glsl_type_of(arg
) for arg
in test_vector
.arguments
)
755 adjusted_glsl_version
= max(
756 glsl_version
, rettype
.version_introduced
,
757 *[t
.version_introduced
for t
in argtypes
])
758 signature
= Signature(
759 name
, template
, adjusted_glsl_version
, extension
, rettype
, argtypes
)
760 if signature
not in test_suite_dict
:
761 test_suite_dict
[signature
] = []
762 test_suite_dict
[signature
].append(test_vector
)
765 def _store_test_vectors(test_suite_dict
, name
, glsl_version
, extension
,
766 test_vectors
, template
=None):
767 """Store multiple test vectors in the appropriate places in
770 If template is supplied, it is used insted as the template for the
771 Signature objects generated.
773 for test_vector
in test_vectors
:
774 _store_test_vector(test_suite_dict
, name
, glsl_version
, extension
,
775 test_vector
, template
=template
)
778 def make_arguments(input_generators
):
779 """Construct a list of tuples of input arguments to test.
781 input_generators is a list, the ith element of which is a sequence
782 of values that are suitable for use as the ith argument of the
785 Output is a list, each element of which is a tuple of arguments to
786 be passed to the function under test. These values are produced
787 by taking the cartesian product of the input sequences.
789 In addition, this function rounds floating point inputs to 32
790 bits, so that there will be no rounding errors when the input
791 values are passed into OpenGL.
794 [round_to_32_bits(x
) for x
in seq
] for seq
in input_generators
]
795 return list(itertools
.product(*input_generators
))
798 def _make_componentwise_test_vectors(test_suite_dict
):
799 """Add test vectors to test_suite_dict for GLSL built-in
800 functions that operate on vectors in componentwise fashion.
801 Examples include sin(), cos(), min(), max(), and clamp().
803 # Make sure atan(x) and atan(x,y) don't misbehave for very large
804 # or very small input values.
806 for exponent
in (-10, -1, 0, 1, 10):
807 atan_inputs
.append(pow(10.0, exponent
))
808 atan_inputs
.append(-pow(10.0, exponent
))
809 # Make a similar set of inputs for acosh(), except don't use any
810 # values < 1, since acosh() is only defined for x >= 1.
811 acosh_inputs
= [1.0 + x
for x
in atan_inputs
if x
>= 0]
812 ints
= [np
.int32(x
) for x
in [-5, -2, -1, 0, 1, 2, 5]]
813 uints
= [np
.uint32(x
) for x
in [0, 1, 2, 5, 34]]
814 bools
= [True, False]
816 def f(name
, arity
, glsl_version
, python_equivalent
,
817 alternate_scalar_arg_indices
, test_inputs
,
818 tolerance_function
=_strict_tolerance
,
820 """Create test vectors for the function with the given name
821 and arity, which was introduced in the given glsl_version.
823 python_equivalent is a Python function which operates on scalars,
824 and simulates the GLSL function. This function should return None
825 in any case where the output of the GLSL function is undefined.
827 If alternate_scalar_arg_indices is not None, also create test
828 vectors for an alternate vectorized version of the function,
829 in which some arguments are scalars.
830 alternate_scalar_arg_indices is a sequence of the indices of
831 the arguments which are scalars.
833 test_inputs is a list, the ith element of which is a list of
834 values that are suitable for use as the ith argument of the
837 If tolerance_function is supplied, it is a function which
838 should be used to compute the tolerance for the test vectors.
839 Otherwise, _strict_tolerance is used.
841 scalar_test_vectors
= _simulate_function(
842 make_arguments(test_inputs
), python_equivalent
, tolerance_function
)
844 test_suite_dict
, name
, glsl_version
, extension
, scalar_test_vectors
)
845 if alternate_scalar_arg_indices
is None:
846 scalar_arg_indices_list
= [()]
848 scalar_arg_indices_list
= [(), alternate_scalar_arg_indices
]
849 for scalar_arg_indices
in scalar_arg_indices_list
:
850 for vector_length
in (2, 3, 4):
852 test_suite_dict
, name
, glsl_version
, extension
,
853 _vectorize_test_vectors(
854 scalar_test_vectors
, scalar_arg_indices
,
857 f('radians', 1, 110, np
.radians
, None, [np
.linspace(-180.0, 180.0, 4)])
858 f('degrees', 1, 110, np
.degrees
, None, [np
.linspace(-np
.pi
, np
.pi
, 4)])
859 f('sin', 1, 110, np
.sin
, None, [np
.linspace(-np
.pi
, np
.pi
, 4)],
861 f('cos', 1, 110, np
.cos
, None, [np
.linspace(-np
.pi
, np
.pi
, 4)],
863 f('tan', 1, 110, np
.tan
, None, [np
.linspace(-np
.pi
, np
.pi
, 4)],
865 f('asin', 1, 110, np
.arcsin
, None, [np
.linspace(-1.0, 1.0, 4)],
867 f('acos', 1, 110, np
.arccos
, None, [np
.linspace(-1.0, 1.0, 4)],
869 f('atan', 1, 110, np
.arctan
, None, [atan_inputs
], _trig_tolerance
)
870 f('atan', 2, 110, _arctan2
, None, [atan_inputs
, atan_inputs
],
872 f('sinh', 1, 130, np
.sinh
, None, [np
.linspace(-2.0, 2.0, 4)],
874 f('cosh', 1, 130, np
.cosh
, None, [np
.linspace(-2.0, 2.0, 4)],
876 f('tanh', 1, 130, np
.tanh
, None, [np
.linspace(-2.0, 2.0, 4)],
878 f('asinh', 1, 130, np
.arcsinh
, None, [atan_inputs
], _trig_tolerance
)
879 f('acosh', 1, 130, np
.arccosh
, None, [acosh_inputs
], _trig_tolerance
)
880 f('atanh', 1, 130, np
.arctanh
, None, [np
.linspace(-0.99, 0.99, 4)],
882 f('pow', 2, 110, _pow
, None, [np
.linspace(0.0, 2.0, 4),
883 np
.linspace(-2.0, 2.0, 4)])
884 f('exp', 1, 110, np
.exp
, None, [np
.linspace(-2.0, 2.0, 4)])
885 f('log', 1, 110, np
.log
, None, [np
.linspace(0.01, 2.0, 4)])
886 f('exp2', 1, 110, _exp2
, None, [np
.linspace(-2.0, 2.0, 4)])
887 f('log2', 1, 110, np
.log2
, None, [np
.linspace(0.01, 2.0, 4)])
888 f('sqrt', 1, 110, np
.sqrt
, None, [np
.linspace(0.0, 2.0, 4)])
889 f('inversesqrt', 1, 110, lambda x
: 1.0/np
.sqrt(x
), None,
890 [np
.linspace(0.1, 2.0, 4)])
891 f('abs', 1, 110, np
.abs, None, [np
.linspace(-1.5, 1.5, 5)])
892 f('abs', 1, 130, np
.abs, None, [ints
])
893 f('sign', 1, 110, np
.sign
, None, [np
.linspace(-1.5, 1.5, 5)])
894 f('sign', 1, 130, np
.sign
, None, [ints
])
895 f('floor', 1, 110, np
.floor
, None, [np
.linspace(-2.0, 2.0, 4)])
897 # Note: with trunc we want to test values in which the floating
898 # point exponent is < 0, > 23 or in the middle. Hence, we append
899 # some numbers to cover all possible scenarios. In addition, we
900 # want to check bitsize barriers (> 32, > 64, etc.) in case the
901 # conversion is done with a cast to and from another int based
903 f('trunc', 1, 130, _trunc
, None,
904 [np
.append(np
.linspace(-2.0, 2.0, 8),
905 [0.0, 45027112.0, -45027112.0,
906 1.9584199e10
, -1.9584199e10
,
907 4.5027112e19
, -4.5027112e19
])])
909 # Note: the direction of rounding used by round() is not specified
910 # for half-integer values, so we test it over a range that doesn't
911 # include exact half-integer values. roundEven() is required to
912 # round half-integer values to the nearest even integer, so we
913 # test it over a range that does include exact half-integer
914 # values. In both cases, we can use numpy's round() function,
915 # because it rounds half-integer values to even, and all other
917 f('round', 1, 130, np
.round, None, [np
.linspace(-2.0, 2.0, 8)])
918 f('roundEven', 1, 130, np
.round, None, [np
.linspace(-2.0, 2.0, 25)])
920 f('ceil', 1, 110, np
.ceil
, None, [np
.linspace(-2.0, 2.0, 4)])
921 f('fract', 1, 110, lambda x
: x
-np
.floor(x
), None,
922 [np
.linspace(-2.0, 2.0, 4)])
923 f('mod', 2, 110, lambda x
, y
: x
-y
*np
.floor(x
/y
), [1],
924 [np
.linspace(-1.9, 1.9, 4), np
.linspace(-2.0, 2.0, 4)])
925 f('min', 2, 110, min, [1],
926 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4)])
927 f('min', 2, 130, min, [1], [ints
, ints
])
928 f('min', 2, 130, min, [1], [uints
, uints
])
929 f('max', 2, 110, max, [1],
930 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4)])
931 f('max', 2, 130, max, [1], [ints
, ints
])
932 f('max', 2, 130, max, [1], [uints
, uints
])
933 f('min3', 2, 110, min, None,
934 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4),
935 np
.linspace(-2.0, 2.0, 4)],
936 extension
="AMD_shader_trinary_minmax")
937 f('min3', 2, 130, min, None, [ints
, ints
, ints
],
938 extension
="AMD_shader_trinary_minmax")
939 f('min3', 2, 130, min, None, [uints
, uints
, uints
],
940 extension
="AMD_shader_trinary_minmax")
941 f('max3', 2, 110, max, None,
942 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4),
943 np
.linspace(-2.0, 2.0, 4)],
944 extension
="AMD_shader_trinary_minmax")
945 f('max3', 2, 130, max, None, [ints
, ints
, ints
],
946 extension
="AMD_shader_trinary_minmax")
947 f('max3', 2, 130, max, None, [uints
, uints
, uints
],
948 extension
="AMD_shader_trinary_minmax")
949 f('mid3', 2, 110, _mid3
, None,
950 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4),
951 np
.linspace(-2.0, 2.0, 4)],
952 extension
="AMD_shader_trinary_minmax")
953 f('mid3', 2, 130, _mid3
, None, [ints
, ints
, ints
],
954 extension
="AMD_shader_trinary_minmax")
955 f('mid3', 2, 130, _mid3
, None, [uints
, uints
, uints
],
956 extension
="AMD_shader_trinary_minmax")
957 f('clamp', 3, 110, _clamp
, [1, 2], [np
.linspace(-2.0, 2.0, 4),
958 np
.linspace(-1.5, 1.5, 3), np
.linspace(-1.5, 1.5, 3)])
959 f('clamp', 3, 130, _clamp
, [1, 2], [ints
, ints
, ints
])
960 f('clamp', 3, 130, _clamp
, [1, 2], [uints
, uints
, uints
])
961 f('mix', 3, 110, lambda x
, y
, a
: x
*(1-a
)+y
*a
, [2],
962 [np
.linspace(-2.0, 2.0, 2), np
.linspace(-3.0, 3.0, 2),
963 np
.linspace(0.0, 1.0, 4)])
964 f('mix', 3, 130, lambda x
, y
, a
: y
if a
else x
, None,
965 [np
.linspace(-2.0, 2.0, 2), np
.linspace(-3.0, 3.0, 2), bools
])
966 f('step', 2, 110, lambda edge
, x
: 0.0 if x
< edge
else 1.0, [0],
967 [np
.linspace(-2.0, 2.0, 4), np
.linspace(-2.0, 2.0, 4)])
968 f('smoothstep', 3, 110, _smoothstep
, [0, 1],
969 [np
.linspace(-1.9, 1.9, 4), np
.linspace(-1.9, 1.9, 4),
970 np
.linspace(-2.0, 2.0, 4)])
972 f('abs', 1, 150, np
.abs, None, [np
.linspace(-10, 15, 54).astype(np
.int64
)],
973 extension
="ARB_gpu_shader_int64")
974 f('sign', 1, 150, np
.sign
, None, [np
.linspace(-15, 15, 5).astype(np
.int64
)],
975 extension
="ARB_gpu_shader_int64")
976 f('min', 2, 150, min, [1],
977 [np
.linspace(-20, 20, 4).astype(np
.int64
), np
.linspace(-20, 20, 4).astype(np
.int64
)],
978 extension
="ARB_gpu_shader_int64")
979 f('min', 2, 150, min, [1],
980 [np
.linspace(20, 90, 4).astype(np
.uint64
), np
.linspace(20, 90, 4).astype(np
.uint64
)],
981 extension
="ARB_gpu_shader_int64")
982 f('max', 2, 150, max, [1],
983 [np
.linspace(-20, 20, 4).astype(np
.int64
), np
.linspace(-20, 20, 4).astype(np
.int64
)],
984 extension
="ARB_gpu_shader_int64")
985 f('max', 2, 150, max, [1],
986 [np
.linspace(20, 90, 4).astype(np
.uint64
), np
.linspace(20, 90, 4).astype(np
.uint64
)],
987 extension
="ARB_gpu_shader_int64")
988 f('clamp', 3, 150, _clamp
, [1, 2], [np
.linspace(-20, 20, 4).astype(np
.int64
),
989 np
.linspace(-15, 15, 3).astype(np
.int64
),
990 np
.linspace(-15, 15, 3).astype(np
.int64
)],
991 extension
="ARB_gpu_shader_int64")
992 f('mix', 3, 150, lambda x
, y
, a
: y
if a
else x
, None,
993 [np
.linspace(-20, 20, 2).astype(np
.int64
), np
.linspace(-30, 30, 2).astype(np
.int64
), bools
],
994 extension
="ARB_gpu_shader_int64")
995 _make_componentwise_test_vectors(test_suite
)
998 def _make_vector_relational_test_vectors(test_suite_dict
):
999 """Add test vectors to test_suite_dict for GLSL built-in functions
1000 that operate on vectors of floats, ints, or bools, but not on
1001 single floats, ints, or bools. Examples include lessThan(),
1005 'v': np
.linspace(-1.5, 1.5, 4),
1006 'i': np
.array([-5, -2, -1, 0, 1, 2, 5], dtype
=np
.int32
),
1007 'u': np
.array([0, 1, 2, 5, 34], dtype
=np
.uint32
),
1008 'b': np
.array([False, True])
1011 def f(name
, arity
, glsl_version
, python_equivalent
, arg_types
,
1012 tolerance_function
=_strict_tolerance
,
1014 """Make test vectors for the function with the given name and
1015 arity, which was introduced in the given glsl_version.
1017 python_equivalent is a Python function which operates on scalars,
1018 and simulates the GLSL function.
1020 arg_types is a string containing 'v' if the function supports
1021 standard "vec" inputs, 'i' if it supports "ivec" inputs, and 'b'
1022 if it supports "bvec" inputs. The output type of the function is
1023 assumed to be the same as its input type.
1025 If tolerance_function is supplied, it is a function which
1026 should be used to compute the tolerance for the test vectors.
1027 Otherwise, _strict_tolerance is used.
1029 for arg_type
in arg_types
:
1030 test_inputs
= [_default_inputs
[arg_type
]]*arity
1031 scalar_test_vectors
= _simulate_function(
1032 make_arguments(test_inputs
), python_equivalent
,
1034 for vector_length
in (2, 3, 4):
1035 _store_test_vectors(
1036 test_suite_dict
, name
, glsl_version
, extension
,
1037 _vectorize_test_vectors(
1038 scalar_test_vectors
, (), vector_length
))
1040 f('lessThan', 2, 110, lambda x
, y
: x
< y
, 'viu')
1041 f('lessThanEqual', 2, 110, lambda x
, y
: x
<= y
, 'viu')
1042 f('greaterThan', 2, 110, lambda x
, y
: x
> y
, 'viu')
1043 f('greaterThanEqual', 2, 110, lambda x
, y
: x
>= y
, 'viu')
1044 f('equal', 2, 110, lambda x
, y
: x
== y
, 'viub')
1045 f('notEqual', 2, 110, lambda x
, y
: x
!= y
, 'viub')
1046 f('not', 1, 110, lambda x
: not x
, 'b')
1047 _make_vector_relational_test_vectors(test_suite
)
1050 def _make_vector_or_matrix_test_vectors(test_suite_dict
):
1051 """Add test vectors to test_suite_dict for GLSL built-in functions
1052 that operate on vectors/matrices as a whole. Examples include
1053 length(), dot(), cross(), normalize(), and refract().
1055 def match_args(*indices
):
1056 """Return a function that determines whether the type of the
1057 arguments at the given indices match.
1065 lambda a, b, c, d: glsl_type_of(b) == glsl_type_of(d)
1067 return lambda *args
: _argument_types_match(args
, indices
)
1069 def match_simple_binop(x
, y
):
1070 """Detemine whether the type of the arguments is compatible
1071 for a simple binary operator (such as '+').
1073 Arguments are compatible if one is a scalar and the other is a
1074 vector/matrix with the same base type, or if they are the same
1077 x_type
= glsl_type_of(x
)
1078 y_type
= glsl_type_of(y
)
1079 if x_type
.base_type
!= y_type
.base_type
:
1081 if x_type
.is_scalar
or y_type
.is_scalar
:
1083 return x_type
== y_type
1085 def match_multiply(x
, y
):
1086 """Determine whether the type of the arguments is compatible
1089 Arguments are compatible if they are scalars, vectors, or
1090 matrices with the same base type, and the vector/matrix sizes
1091 are properly matched.
1093 x_type
= glsl_type_of(x
)
1094 y_type
= glsl_type_of(y
)
1095 if x_type
.base_type
!= y_type
.base_type
:
1097 if x_type
.is_scalar
or y_type
.is_scalar
:
1099 if x_type
.is_vector
and y_type
.is_matrix
:
1100 # When multiplying vector * matrix, the vector is
1101 # transposed to a row vector. So its row count must match
1102 # the row count of the matrix.
1103 return x_type
.num_rows
== y_type
.num_rows
1104 elif x_type
.is_vector
:
1105 assert y_type
.is_vector
1106 # When multiplying vector * vector, the multiplication is
1107 # done componentwise, so the types must match exactly.
1108 return x_type
== y_type
1110 assert x_type
.is_matrix
1111 # When multiplying matrix * matrix or matrix * vector, a
1112 # standard linear algebraic multiply is used, so x's
1113 # column count must match y's row count.
1114 return x_type
.num_cols
== y_type
.num_rows
1116 def match_shift(x
, y
):
1117 """Determine whether the type of the arguments is compatible
1118 for shift operations.
1120 Arguments are compatible if they are the same length or the
1121 first one is a vector and the second is a scalar. Their base
1122 types need not be the same, but they both must be integral.
1124 x_type
= glsl_type_of(x
)
1125 y_type
= glsl_type_of(y
)
1126 if x_type
.base_type
not in (glsl_int
, glsl_uint
, glsl_int64_t
, glsl_uint64_t
):
1128 if y_type
.base_type
not in (glsl_int
, glsl_uint
):
1130 if y_type
.is_scalar
:
1132 assert not x_type
.is_matrix
1133 assert not y_type
.is_matrix
1134 return x_type
.num_rows
== y_type
.num_rows
1136 def match_assignment_operators(x
, y
):
1137 """ Determine when scalar and matrix arithmetic works
1139 A matrix and a scalar can be combined, but only when being assigned
1140 into a large enough type.
1143 x_type
= glsl_type_of(x
)
1144 y_type
= glsl_type_of(y
)
1145 if x_type
.base_type
!= y_type
.base_type
:
1147 if y_type
.is_scalar
:
1149 return x_type
== y_type
1151 def match_assignment_multiply(x
, y
):
1152 """Determine whether the type of the arguments is compatible
1155 Arguments are compatible if they are scalars, vectors, or
1156 matrices with the same base type, and the vector/matrix sizes
1157 are properly matched, and that y is scalar
1159 x_type
= glsl_type_of(x
)
1160 y_type
= glsl_type_of(y
)
1161 if x_type
.base_type
!= y_type
.base_type
:
1163 if y_type
.is_scalar
:
1165 if x_type
.is_scalar
:
1167 if x_type
.is_vector
and y_type
.is_matrix
:
1168 # When multiplying vector * matrix, the vector is
1169 # transposed to a row vector. So its row count must match
1170 # the row count of the matrix.
1171 return x_type
.num_rows
== y_type
.num_rows
== y_type
.num_cols
1172 elif x_type
.is_vector
:
1173 assert y_type
.is_vector
1174 # When multiplying vector * vector, the multiplication is
1175 # done componentwise, so the types must match exactly.
1176 return x_type
== y_type
1178 assert x_type
.is_matrix
1179 # When multiplying matrix * matrix or matrix * vector, a
1180 # standard linear algebraic multiply is used, so x's
1181 # column count must match y's row count.
1182 return (x_type
.num_cols
== y_type
.num_rows
and
1183 x_type
.num_cols
== y_type
.num_cols
)
1185 bools
= [False, True]
1186 bvecs
= [np
.array(bs
) for bs
in itertools
.product(bools
, bools
)] + \
1187 [np
.array(bs
) for bs
in itertools
.product(bools
, bools
, bools
)] + \
1188 [np
.array(bs
) for bs
in itertools
.product(bools
, bools
, bools
, bools
)]
1189 ints
= [np
.int32(x
) for x
in [12, -6, 76, -32, 0]]
1191 [np
.int32(x
) for x
in [-31, -25, -5, -2, -1, 0, 1, 2, 5, 25, 31]]
1193 np
.array([38, 35], dtype
=np
.int32
),
1194 np
.array([64, -9], dtype
=np
.int32
),
1195 np
.array([64, 9], dtype
=np
.int32
),
1196 np
.array([-36, 32, -88], dtype
=np
.int32
),
1197 np
.array([36, 32, 88], dtype
=np
.int32
),
1198 np
.array([59, 77, 68], dtype
=np
.int32
),
1199 np
.array([-64, 72, 88, -76], dtype
=np
.int32
),
1200 np
.array([64, 72, 88, 76], dtype
=np
.int32
),
1201 np
.array([-24, 40, -23, 64], dtype
=np
.int32
),
1202 np
.array([24, 40, 23, 64], dtype
=np
.int32
),
1205 np
.array([13, 26], dtype
=np
.int32
),
1206 np
.array([-2, 26], dtype
=np
.int32
),
1207 np
.array([2, 26], dtype
=np
.int32
),
1208 np
.array([22, -23, 4], dtype
=np
.int32
),
1209 np
.array([22, 23, 4], dtype
=np
.int32
),
1210 np
.array([-19, 1, -13], dtype
=np
.int32
),
1211 np
.array([19, 1, 13], dtype
=np
.int32
),
1212 np
.array([16, 24, -23, -25], dtype
=np
.int32
),
1213 np
.array([16, 24, 23, 25], dtype
=np
.int32
),
1214 np
.array([-23, -12, 14, 19], dtype
=np
.int32
),
1215 np
.array([23, 12, 14, 19], dtype
=np
.int32
),
1217 uints
= [np
.uint32(x
) for x
in [0, 6, 12, 32, 74]]
1218 small_uints
= [np
.uint32(x
) for x
in [0, 1, 2, 5, 25, 31]]
1219 large_uints
= [np
.uint32(x
) for x
in [0xdeadbeef, 0xaffeaffe, 0xbadbad]]
1221 np
.array([38, 35], dtype
=np
.uint32
),
1222 np
.array([64, 9], dtype
=np
.uint32
),
1223 np
.array([36, 32, 88], dtype
=np
.uint32
),
1224 np
.array([59, 77, 68], dtype
=np
.uint32
),
1225 np
.array([66, 72, 87, 75], dtype
=np
.uint32
),
1226 np
.array([24, 40, 23, 74], dtype
=np
.uint32
)
1229 np
.array([13, 26], dtype
=np
.uint32
),
1230 np
.array([2, 26], dtype
=np
.uint32
),
1231 np
.array([22, 23, 4], dtype
=np
.uint32
),
1232 np
.array([19, 1, 13], dtype
=np
.uint32
),
1233 np
.array([16, 24, 23, 25], dtype
=np
.uint32
),
1234 np
.array([23, 12, 14, 19], dtype
=np
.uint32
),
1236 nz_floats
= [-1.33, 0.85]
1237 floats
= [0.0] + nz_floats
1239 np
.array([-0.10, -1.20]),
1240 np
.array([-0.42, 0.48]),
1241 np
.array([-0.03, -0.85, -0.94]),
1242 np
.array([1.67, 0.66, 1.87]),
1243 np
.array([-1.65, 1.33, 1.93, 0.76]),
1244 np
.array([0.80, -0.15, -0.51, 0.0])
1246 nz_floats_vecs
= nz_floats
+ vecs
1248 np
.array([-0.03, -0.85, -0.94]),
1249 np
.array([1.67, 0.66, 1.87]),
1251 norm_floats_vecs
= [_normalize(x
) for x
in nz_floats_vecs
]
1253 np
.array([[ 1.60, 0.76],
1254 [ 1.53, -1.00]]), # mat2
1255 np
.array([[-0.13, -0.87],
1256 [-1.40, 1.40]]), # mat2
1257 np
.array([[-1.11, 1.67, -0.41],
1258 [ 0.13, 1.09, -0.02],
1259 [ 0.56, 0.95, 0.24]]), # mat3
1260 np
.array([[-1.69, -0.46, -0.18],
1261 [-1.09, 1.75, 2.00],
1262 [-1.53, -0.70, -1.47]]), # mat3
1263 np
.array([[-1.00, -0.55, -1.08, 1.79],
1264 [ 1.77, 0.62, 0.48, -1.35],
1265 [ 0.09, -0.71, -1.39, -1.21],
1266 [-0.91, -1.82, -1.43, 0.72]]), # mat4
1267 np
.array([[ 0.06, 1.31, 1.52, -1.96],
1268 [ 1.60, -0.32, 0.51, -1.84],
1269 [ 1.25, 0.45, 1.90, -0.72],
1270 [-0.16, 0.45, -0.88, 0.39]]), # mat4
1272 mats
= squaremats
+ [
1273 np
.array([[ 0.09, 1.30, 1.25],
1274 [-1.19, 0.08, 1.08]]), # mat3x2
1275 np
.array([[-0.36, -1.08, -0.60],
1276 [-0.53, 0.88, -1.79]]), # mat3x2
1277 np
.array([[-0.46, 1.94],
1279 [ 1.03, -0.50]]), # mat2x3
1280 np
.array([[ 1.38, -1.08],
1282 [ 1.00, -0.74]]), # mat2x3
1283 np
.array([[ 1.81, -0.87, 0.81, 0.65],
1284 [-1.16, -1.52, 0.25, -1.51]]), # mat4x2
1285 np
.array([[ 1.93, -1.63, 0.29, 1.60],
1286 [ 0.49, 0.27, 0.14, 0.94]]), # mat4x2
1287 np
.array([[ 0.16, -1.69],
1290 [-0.02, -1.21]]), # mat2x4
1291 np
.array([[-1.02, 0.74],
1294 [ 0.30, 1.13]]), # mat2x4
1295 np
.array([[-0.27, -1.38, -1.41, -0.12],
1296 [-0.17, -0.56, 1.47, 1.86],
1297 [-1.85, -1.29, 1.77, 0.01]]), # mat4x3
1298 np
.array([[-0.47, -0.15, 1.97, -1.05],
1299 [-0.20, 0.53, -1.82, -1.41],
1300 [-1.39, -0.19, 1.62, 1.58]]), # mat4x3
1301 np
.array([[ 1.42, -0.86, 0.27],
1302 [ 1.80, -1.74, 0.04],
1303 [-1.88, -0.37, 0.43],
1304 [ 1.37, 1.90, 0.71]]), # mat3x4
1305 np
.array([[-1.72, 0.09, 0.45],
1306 [-0.31, -1.58, 1.92],
1307 [ 0.14, 0.18, -0.56],
1308 [ 0.40, -0.77, 1.76]]), # mat3x4
1311 int64s
= [np
.int64(x
) for x
in [
1320 -135763469567146206]]
1321 uint64s
= [np
.uint64(x
) for x
in [
1331 11654173250180970009]]
1334 np
.array([-10, -12], dtype
=np
.int64
),
1335 np
.array([-42, 48], dtype
=np
.int64
),
1336 np
.array([-1333333333333333259, 85, 94], dtype
=np
.int64
),
1337 np
.array([167, 66, 187], dtype
=np
.int64
),
1338 np
.array([165, 133, 193, 76], dtype
=np
.int64
),
1339 np
.array([80, -15, -51, 0], dtype
=np
.int64
)
1341 int64_i64vecs
= int64s
+ int64vecs
1343 np
.array([-3, -85, -94], dtype
=np
.int64
),
1344 np
.array([ 1333333333333333259, 66, 87], dtype
=np
.int64
),
1348 np
.array([10, 12], dtype
=np
.uint64
),
1349 np
.array([42, 48], dtype
=np
.uint64
),
1350 np
.array([1333333333333333259, 85, 94], dtype
=np
.uint64
),
1351 np
.array([167, 66, 187], dtype
=np
.uint64
),
1352 np
.array([165, 133, 193, 76], dtype
=np
.uint64
),
1353 np
.array([80, 15, 51, 0], dtype
=np
.uint64
)
1355 uint64_u64vecs
= uint64s
+ uint64vecs
1357 np
.array([3, 85, 94], dtype
=np
.uint64
),
1358 np
.array([ 1333333333333333259, 66, 87], dtype
=np
.uint64
),
1361 def f(name
, arity
, glsl_version
, python_equivalent
,
1362 filter, test_inputs
, tolerance_function
=_strict_tolerance
,
1365 """Make test vectors for the function with the given name and
1366 arity, which was introduced in the given glsl_version.
1368 python_equivalent is a Python function which simulates the GLSL
1369 function. This function should return None in any case where the
1370 output of the GLSL function is undefined. However, it need not
1371 check that the lengths of the input vectors are all the same.
1373 If filter is not None, it will be called with each set of
1374 arguments, and test cases will only be generated if the filter
1377 test_inputs is a list, the ith element of which is a list of
1378 vectors and/or scalars that are suitable for use as the ith
1379 argument of the function.
1381 If tolerance_function is supplied, it is a function which
1382 should be used to compute the tolerance for the test vectors.
1383 Otherwise, _strict_tolerance is used.
1385 If template is supplied, it is used insted as the template for
1386 the Signature objects generated.
1388 test_inputs
= make_arguments(test_inputs
)
1389 if filter is not None:
1391 [arguments
for arguments
in test_inputs
if filter(*arguments
)]
1392 _store_test_vectors(
1393 test_suite_dict
, name
, glsl_version
, extension
,
1395 test_inputs
, python_equivalent
, tolerance_function
),
1398 f('op-assign-add', 2, 110, lambda x
, y
: x
+ y
, match_assignment_operators
,
1399 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1400 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1401 template
='{0};\n result += {1}')
1402 # This can generate an overflow warning, this is expected
1403 with warnings
.catch_warnings():
1404 warnings
.simplefilter('ignore', RuntimeWarning)
1405 f('op-assign-sub', 2, 110,
1406 lambda x
, y
: x
- y
, match_assignment_operators
,
1407 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1408 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1409 template
='{0};\n result -= {1}')
1410 f('op-assign-mult', 2, 110, _multiply
, match_assignment_multiply
,
1411 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1412 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1413 template
='{0};\n result *= {1}')
1414 f('op-assign-div', 2, 110, _divide
, match_assignment_operators
,
1415 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1416 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1417 template
='{0};\n result /= {1}')
1418 f('op-assign-div-large', 2, 130, _divide
, match_assignment_operators
,
1419 [large_uints
, large_uints
+small_uints
],
1420 template
='{0};\n result /= {1}')
1421 f('op-assign-mod', 2, 130, _modulus
, match_assignment_operators
,
1422 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1423 template
='{0};\n result %= {1}')
1424 f('op-assign-bitand', 2, 130, lambda x
, y
: x
& y
,
1425 match_assignment_operators
,
1426 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1427 template
='{0}; result &= {1}')
1428 f('op-assign-bitor', 2, 130, lambda x
, y
: x | y
,
1429 match_assignment_operators
,
1430 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1431 template
='{0};\n result |= {1}')
1432 f('op-assign-bitxor', 2, 130, lambda x
, y
: x ^ y
,
1433 match_assignment_operators
,
1434 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1435 template
='{0};\n result ^= {1}')
1436 f('op-assign-lshift', 2, 130, _lshift
, match_shift
,
1437 [small_ints
+small_ivecs
+small_uints
+small_uvecs
,
1438 small_ints
+small_ivecs
+small_uints
+small_uvecs
],
1439 template
='{0}; result <<= {1}')
1440 f('op-assign-rshift', 2, 130, _rshift
, match_shift
,
1441 [small_ints
+small_ivecs
+small_uints
+small_uvecs
,
1442 small_ints
+small_ivecs
+small_uints
+small_uvecs
],
1443 template
='{0}; result >>= {1}')
1444 f('op-add', 2, 110, lambda x
, y
: x
+ y
, match_simple_binop
,
1445 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1446 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1447 template
='({0} + {1})')
1448 # This can generate an overflow warning, this is expected
1449 with warnings
.catch_warnings():
1450 warnings
.simplefilter('ignore', RuntimeWarning)
1451 f('op-sub', 2, 110, lambda x
, y
: x
- y
, match_simple_binop
,
1452 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1453 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1454 template
='({0} - {1})')
1455 f('op-mult', 2, 110, _multiply
, match_multiply
,
1456 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1457 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1458 template
='({0} * {1})')
1459 f('op-div', 2, 110, _divide
, match_simple_binop
,
1460 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
,
1461 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
],
1462 template
='({0} / {1})')
1463 f('op-div-large', 2, 130, _divide
, match_simple_binop
,
1464 [large_uints
, large_uints
+small_uints
], template
='({0} / {1})')
1465 f('op-mod', 2, 130, _modulus
, match_simple_binop
,
1466 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
], template
='({0} % {1})')
1467 f('op-uplus', 1, 110, lambda x
: +x
, None,
1468 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
], template
='(+ {0})')
1469 f('op-neg', 1, 110, lambda x
: -x
, None,
1470 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
], template
='(- {0})')
1471 f('op-gt', 2, 110, lambda x
, y
: x
> y
, match_args(0, 1),
1472 [ints
+uints
+floats
, ints
+uints
+floats
], template
='({0} > {1})')
1473 f('op-lt', 2, 110, lambda x
, y
: x
< y
, match_args(0, 1),
1474 [ints
+uints
+floats
, ints
+uints
+floats
], template
='({0} < {1})')
1475 f('op-ge', 2, 110, lambda x
, y
: x
>= y
, match_args(0, 1),
1476 [ints
+uints
+floats
, ints
+uints
+floats
], template
='({0} >= {1})')
1477 f('op-le', 2, 110, lambda x
, y
: x
<= y
, match_args(0, 1),
1478 [ints
+uints
+floats
, ints
+uints
+floats
], template
='({0} <= {1})')
1479 f('op-eq', 2, 110, _equal
, match_args(0, 1),
1480 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
,
1481 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
],
1482 template
='({0} == {1})')
1483 f('op-ne', 2, 110, _not_equal
, match_args(0, 1),
1484 [floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
,
1485 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
],
1486 template
='({0} != {1})')
1487 f('op-and', 2, 110, lambda x
, y
: x
and y
, None, [bools
, bools
],
1488 template
='({0} && {1})')
1489 f('op-or', 2, 110, lambda x
, y
: x
or y
, None, [bools
, bools
],
1490 template
='({0} || {1})')
1491 f('op-xor', 2, 110, lambda x
, y
: x
!= y
, None, [bools
, bools
],
1492 template
='({0} ^^ {1})')
1493 f('op-not', 1, 110, lambda x
: not x
, None, [bools
], template
='(! {0})')
1494 f('op-selection', 3, 110, lambda x
, y
, z
: y
if x
else z
, match_args(1, 2),
1495 [bools
, floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
,
1496 floats
+vecs
+mats
+ints
+ivecs
+uints
+uvecs
+bools
+bvecs
],
1497 template
='({0} ? {1} : {2})')
1498 f('op-complement', 1, 130, lambda x
: ~x
, None, [ints
+ivecs
+uints
+uvecs
],
1500 f('op-lshift', 2, 130, _lshift
, match_shift
,
1501 [small_ints
+small_ivecs
+small_uints
+small_uvecs
,
1502 small_ints
+small_ivecs
+small_uints
+small_uvecs
],
1503 template
='({0} << {1})')
1504 f('op-rshift', 2, 130, _rshift
, match_shift
,
1505 [small_ints
+small_ivecs
+small_uints
+small_uvecs
,
1506 small_ints
+small_ivecs
+small_uints
+small_uvecs
],
1507 template
='({0} >> {1})')
1508 f('op-bitand', 2, 130, lambda x
, y
: x
& y
, match_simple_binop
,
1509 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1510 template
='({0} & {1})')
1511 f('op-bitor', 2, 130, lambda x
, y
: x | y
, match_simple_binop
,
1512 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1513 template
='({0} | {1})')
1514 f('op-bitxor', 2, 130, lambda x
, y
: x ^ y
, match_simple_binop
,
1515 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1516 template
='({0} ^ {1})')
1517 f('op-bitand-neg', 2, 130, lambda x
, y
: x
& (-y
), match_simple_binop
,
1518 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1519 template
='({0} & (- {1}))')
1520 f('op-bitand-not', 2, 130, lambda x
, y
: x
& (~y
), match_simple_binop
,
1521 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1522 template
='({0} & (~ {1}))')
1523 f('op-bitor-neg', 2, 130, lambda x
, y
: x |
(-y
), match_simple_binop
,
1524 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1525 template
='({0} | (- {1}))')
1526 f('op-bitor-not', 2, 130, lambda x
, y
: x |
(~y
), match_simple_binop
,
1527 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1528 template
='({0} | (~ {1}))')
1529 f('op-bitxor-neg', 2, 130, lambda x
, y
: x ^
(-y
), match_simple_binop
,
1530 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1531 template
='({0} ^ (- {1}))')
1532 f('op-bitxor-not', 2, 130, lambda x
, y
: x ^
(~y
), match_simple_binop
,
1533 [ints
+ivecs
+uints
+uvecs
, ints
+ivecs
+uints
+uvecs
],
1534 template
='({0} ^ (~ {1}))')
1535 f('op-bitand-neg-abs', 2, 130, lambda x
, y
: x
& (-abs(y
)), match_simple_binop
,
1536 [ints
+ivecs
, ints
+ivecs
],
1537 template
='({0} & (- abs({1})))')
1538 f('op-bitand-not-abs', 2, 130, lambda x
, y
: x
& (~
abs(y
)), match_simple_binop
,
1539 [ints
+ivecs
, ints
+ivecs
],
1540 template
='({0} & (~ abs({1})))')
1541 f('op-bitor-neg-abs', 2, 130, lambda x
, y
: x |
(-abs(y
)), match_simple_binop
,
1542 [ints
+ivecs
, ints
+ivecs
],
1543 template
='({0} | (- abs({1})))')
1544 f('op-bitor-not-abs', 2, 130, lambda x
, y
: x |
(~
abs(y
)), match_simple_binop
,
1545 [ints
+ivecs
, ints
+ivecs
],
1546 template
='({0} | (~ abs({1})))')
1547 f('op-bitxor-neg-abs', 2, 130, lambda x
, y
: x ^
(-abs(y
)), match_simple_binop
,
1548 [ints
+ivecs
, ints
+ivecs
],
1549 template
='({0} ^ (- abs({1})))')
1550 f('op-bitxor-not-abs', 2, 130, lambda x
, y
: x ^
(~
abs(y
)), match_simple_binop
,
1551 [ints
+ivecs
, ints
+ivecs
],
1552 template
='({0} ^ (~ abs({1})))')
1553 f('op-bitand-abs-neg', 2, 130, lambda x
, y
: x
& abs(-y
), match_simple_binop
,
1554 [ints
+ivecs
, ints
+ivecs
],
1555 template
='({0} & abs(- {1}))')
1556 f('op-bitand-abs-not', 2, 130, lambda x
, y
: x
& abs(~y
), match_simple_binop
,
1557 [ints
+ivecs
, ints
+ivecs
],
1558 template
='({0} & abs(~ {1}))')
1559 f('op-bitor-abs-neg', 2, 130, lambda x
, y
: x |
abs(-y
), match_simple_binop
,
1560 [ints
+ivecs
, ints
+ivecs
],
1561 template
='({0} | abs(- {1}))')
1562 f('op-bitor-abs-not', 2, 130, lambda x
, y
: x |
abs(~y
), match_simple_binop
,
1563 [ints
+ivecs
, ints
+ivecs
],
1564 template
='({0} | abs(~ {1}))')
1565 f('op-bitxor-abs-neg', 2, 130, lambda x
, y
: x ^
abs(-y
), match_simple_binop
,
1566 [ints
+ivecs
, ints
+ivecs
],
1567 template
='({0} ^ abs(- {1}))')
1568 f('op-bitxor-abs-not', 2, 130, lambda x
, y
: x ^
abs(~y
), match_simple_binop
,
1569 [ints
+ivecs
, ints
+ivecs
],
1570 template
='({0} ^ abs(~ {1}))')
1571 f('length', 1, 110, np
.linalg
.norm
, None, [floats
+vecs
])
1572 f('distance', 2, 110, lambda x
, y
: np
.linalg
.norm(x
-y
), match_args(0, 1),
1573 [floats
+vecs
, floats
+vecs
])
1574 f('dot', 2, 110, np
.dot
, match_args(0, 1), [floats
+vecs
, floats
+vecs
])
1575 f('cross', 2, 110, np
.cross
, match_args(0, 1), [vec3s
, vec3s
],
1576 _cross_product_tolerance
)
1577 f('normalize', 1, 110, _normalize
, None, [nz_floats_vecs
])
1578 f('faceforward', 3, 110, _faceforward
, match_args(0, 1, 2),
1579 [floats
+vecs
, floats
+vecs
, floats
+vecs
])
1580 f('reflect', 2, 110, _reflect
, match_args(0, 1),
1581 [floats
+vecs
, norm_floats_vecs
])
1582 f('refract', 3, 110, _refract
, match_args(0, 1),
1583 [norm_floats_vecs
, norm_floats_vecs
, [0.5, 2.0]])
1585 # Note: technically matrixCompMult operates componentwise.
1586 # However, since it is the only componentwise function to operate
1587 # on matrices, it is easier to generate test cases for it here
1588 # than to add matrix support to _make_componentwise_test_vectors.
1589 f('matrixCompMult', 2, 110, lambda x
, y
: x
*y
, match_args(0, 1),
1592 f('outerProduct', 2, 120, np
.outer
, None, [vecs
, vecs
])
1593 f('transpose', 1, 120, np
.transpose
, None, [mats
])
1594 f('any', 1, 110, any
, None, [bvecs
])
1595 f('all', 1, 110, all
, None, [bvecs
])
1597 f('inverse', 1, 140, np
.linalg
.inv
, None, [squaremats
])
1599 f('determinant', 1, 150, np
.linalg
.det
, None, [squaremats
])
1601 f('op-add', 2, 150, lambda x
, y
: x
+ y
, match_simple_binop
,
1602 [int64s
+int64vecs
+uint64s
+uint64vecs
,
1603 int64s
+int64vecs
+uint64s
+uint64vecs
],
1604 template
='({0} + {1})',
1605 extension
="ARB_gpu_shader_int64")
1606 with warnings
.catch_warnings():
1607 warnings
.simplefilter('ignore', RuntimeWarning)
1608 f('op-sub', 2, 150, lambda x
, y
: x
- y
, match_simple_binop
,
1609 [int64s
+int64vecs
+uint64s
+uint64vecs
,
1610 int64s
+int64vecs
+uint64s
+uint64vecs
],
1611 template
='({0} - {1})',
1612 extension
="ARB_gpu_shader_int64")
1613 f('op-mult', 2, 150, _multiply
, match_multiply
,
1614 [int64s
+int64vecs
+uint64s
+uint64vecs
,
1615 int64s
+int64vecs
+uint64s
+uint64vecs
],
1616 template
='({0} * {1})',
1617 extension
="ARB_gpu_shader_int64")
1618 f('op-div', 2, 150, _divide
, match_simple_binop
,
1619 [int64s
+int64vecs
+uint64s
+uint64vecs
,
1620 int64s
+int64vecs
+uint64s
+uint64vecs
],
1621 template
='({0} / {1})',
1622 extension
="ARB_gpu_shader_int64")
1623 f('op-mod', 2, 150, _modulus
, match_simple_binop
,
1624 [int64s
+int64vecs
+uint64s
+uint64vecs
,
1625 int64s
+int64vecs
+uint64s
+uint64vecs
],
1626 template
='({0} % {1})',
1627 extension
="ARB_gpu_shader_int64")
1628 f('op-gt', 2, 150, lambda x
, y
: x
> y
, match_args(0, 1),
1631 template
= '({0} > {1})',
1632 extension
="ARB_gpu_shader_int64")
1633 f('op-lt', 2, 150, lambda x
, y
: x
< y
, match_args(0, 1),
1636 template
= '({0} < {1})',
1637 extension
="ARB_gpu_shader_int64")
1638 f('op-ge', 2, 150, lambda x
, y
: x
>= y
, match_args(0, 1),
1641 template
= '({0} >= {1})',
1642 extension
="ARB_gpu_shader_int64")
1643 f('op-le', 2, 150, lambda x
, y
: x
<= y
, match_args(0, 1),
1646 template
= '({0} <= {1})',
1647 extension
="ARB_gpu_shader_int64")
1648 f('op-eq', 2, 150, lambda x
, y
: x
== y
, match_args(0, 1),
1651 template
= '({0} == {1})',
1652 extension
="ARB_gpu_shader_int64")
1653 f('op-ne', 2, 150, lambda x
, y
: x
!= y
, match_args(0, 1),
1656 template
= '({0} != {1})',
1657 extension
="ARB_gpu_shader_int64")
1658 f('op-bitand', 2, 150, lambda x
, y
: x
& y
, match_simple_binop
,
1659 [int64s
+uint64s
, int64s
+uint64s
],
1660 template
='({0} & {1})',
1661 extension
="ARB_gpu_shader_int64")
1662 f('op-bitor', 2, 150, lambda x
, y
: x | y
, match_simple_binop
,
1663 [int64s
+uint64s
, int64s
+uint64s
],
1664 template
='({0} | {1})',
1665 extension
="ARB_gpu_shader_int64")
1666 f('op-bitxor', 2, 150, lambda x
, y
: x ^ y
, match_simple_binop
,
1667 [int64s
+uint64s
, int64s
+uint64s
],
1668 template
='({0} ^ {1})',
1669 extension
="ARB_gpu_shader_int64")
1670 f('op-lshift', 2, 150, _lshift
, match_shift
,
1673 template
='({0} << {1})',
1674 extension
="ARB_gpu_shader_int64")
1675 f('op-rshift', 2, 150, _rshift
, match_shift
,
1678 template
='({0} >> {1})',
1679 extension
="ARB_gpu_shader_int64")
1680 _make_vector_or_matrix_test_vectors(test_suite
)
1683 def _check_signature_safety(test_suite_dict
):
1684 """As a final safety check, verify that for each possible
1685 combination of name and argtypes, there is exactly one
1688 name_argtype_combos
= set()
1689 for signature
in test_suite_dict
:
1690 name_argtype_combo
= (signature
.name
, signature
.argtypes
)
1691 if name_argtype_combo
in name_argtype_combos
:
1693 'Duplicate signature found for {0}'.format(name_argtype_combo
))
1694 name_argtype_combos
.add(name_argtype_combo
)
1695 _check_signature_safety(test_suite
)