3 # Copyright © 2016 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 """Generate fp64 and int64 types conversion tests."""
26 from __future__
import print_function
, division
, absolute_import
35 from templates
import template_dir
36 from modules
import utils
38 TEMPLATES
= template_dir(os
.path
.basename(os
.path
.splitext(__file__
)[0]))
40 # pylint: disable=bad-whitespace,line-too-long,bad-continuation
41 DOUBLE_INFS
= ['0xfff0000000000000', # -inf
42 '0x7ff0000000000000'] # +inf
44 DOUBLE_NEG_ZERO
= ['0x8000000000000000'] # Negative underflow (-0.0)
46 DOUBLE_POS_ZERO
= ['0x0000000000000000'] # Positive underflow (+0.0)
48 # Double values causing an underflow to zero in any other type
49 DOUBLE_DENORMAL_VALUES
= ['0x800fffffffffffff', # Negative maximum denormalized -- Denormalized may be flushed to 0
50 '0x8000000000000001', # Negative minimum denormalized -- Denormalized may be flushed to 0
51 '0x0000000000000001', # Positive minimum denormalized -- Denormalized may be flushed to 0
52 '0x000fffffffffffff'] # Positive maximum denormalized -- Denormalized may be flushed to 0
54 DOUBLE_NORMAL_VALUES
= ['0x8010000000000000', # Negative minimum normalized
55 '0x0010000000000000'] # Positive minimum normalized
58 DOUBLE_FLOAT_INFS
= ['0xc7effffff0000000', # Negative overflow (-inf)
59 '0x47effffff0000000'] # Positive overflow (+inf)
61 DOUBLE_FLOAT_VALUES
= ['0xc7efffffefffffff', # Negative maximum normalized
62 '0xc170000000000000', # -16777216.0
63 '0xc014000000000000', # -5.0
64 '0xbfff25ce60000000', # -1.9467300176620483
65 '0xb80fffffe0000000', # Negative minimum normalized
66 '0xb69fffffffffffff', # Negative underflow
67 '0x369fffffffffffff', # Positive underflow
68 '0x380fffffe0000000', # Positive minimum normalized
69 '0x3fff25ce60000000', # +1.9467300176620483
70 '0x4014000000000000', # +5.0
71 '0x4170000000000000', # +16777216.0
72 '0x47efffffefffffff'] # Positive maximum normalized
74 DOUBLE_UINT_VALUES
= ['0xbfeccccccccccccd', # -0.9
75 #'0x8010000000000000', # Negative minimum normalized -- Already checked
76 #'0x800fffffffffffff', # Negative maximum denormalized -- Already checked
77 #'0x8000000000000001', # Negative minimum denormalized -- Already checked
78 #'0x8000000000000000', # Negative minimum (-0) -- Already checked
79 #'0x0000000000000000', # Positive minimum (+0) -- Already checked
80 '0x3fff25ce60000000', # +1.9467300176620483
81 '0x4014000000000000', # +5.0
82 '0x4170000000000000', # +16777216.0
83 '0x41dfffffffc00000', # Signed int low frontier (+2147483647)
84 '0x41e0000000000000', # Signed int up frontier (+2147483648)
85 '0x41efffffffe00000'] # Maximum (+4294967295)
87 DOUBLE_INT_VALUES
= ['0xc1e0000000000000', # Minimum (-2147483648)
88 '0xc170000000000000', # -16777216.0
89 '0xc014000000000000', # -5.0
90 '0xbfff25ce60000000', # -1.9467300176620483
91 #'0x8000000000000000', # Negative minimum (-0) -- Already checked
92 #'0x0000000000000000', # Minimum (+0) -- Already checked
93 '0x3fff25ce60000000', # +1.9467300176620483
94 '0x4014000000000000', # +5.0
95 '0x4170000000000000', # +16777216.0
96 '0x41dfffffffc00000'] # Maximum (+2147483647)
98 DOUBLE_BOOL_VALUES
= [#'0x8010000000000000', # Minimum negative True value -- Already checked
99 #'0x0000000000000000', # False -- Already checked
100 #'0x0010000000000000', # Minimum positive True value -- Already checked
103 FLOAT_INFS
= ['0xff800000', # -inf
106 FLOAT_NEG_ZERO
= ['0x80000000'] # Negative underflow (-0.0)
108 FLOAT_POS_ZERO
= ['0x00000000'] # Positive underflow (+0.0)
110 FLOAT_VALUES
= ['0xff7fffff', # Negative maximum normalized
111 '0xcb800000', # -16777216.0
113 '0xbff92e73', # -1.9467300176620483
114 '0x80800000', # Negative minimum normalized
115 #'0x807fffff', # Negative maximum denormalized -- Denormalized may be flushed to 0
116 #'0x80000001', # Negative minimum denormalized -- Denormalized may be flushed to 0
117 #'0x00000001', # Positive minimum denormalized -- Denormalized may be flushed to 0
118 #'0x007fffff', # Positive maximum denormalized -- Denormalized may be flushed to 0
119 '0x00800000', # Positive minimum normalized
120 '0x3ff92e73', # +1.9467300176620483
122 '0x4b800000', # +16777216.0
123 '0x7f7fffff'] # Positive maximum normalized
125 FLOAT_INT64_VALUES
= ['0xcf800000', # -4294967296.0
126 '0xcb800000', # -16777216.0
128 '0xbff92e73', # -1.9467300176620483
129 '0x80800000', # Negative minimum normalized
130 '0x807fffff', # Negative maximum denormalized
131 '0x80000001', # Negative minimum denormalized
132 '0x00000001', # Positive minimum denormalized
133 '0x007fffff', # Positive maximum denormalized
134 '0x00800000', # Positive minimum normalized
135 '0x3ff92e73', # +1.9467300176620483
137 '0x4b800000', # +16777216.0
138 '0x4f800000'] # +4294967296.0
140 FLOAT_UINT64_VALUES
= ['0x00000001', # Positive minimum denormalized
141 '0x007fffff', # Positive maximum denormalized
142 '0x00800000', # Positive minimum normalized
143 '0x3ff92e73', # +1.9467300176620483
145 '0x4b800000', # +16777216.0
146 '0x4f800000'] # +4294967296.0
148 UINT64_VALUES
= ['0', # Minimum
150 '2147483647', # Signed int32 low frontier
151 '2147483648', # Signed int32 up frontier
152 '4294967295', # Maximum unsigned int32
154 '9223372036854775807', # Signed int64 low frontier
155 '9223372036854775808', # Signed int64 up frontier
156 '18446744073709551615'] # Maximum
158 INT64_VALUES
= ['-9223372036854775808', # Minimum
166 '2147483647', # Signed int32 low frontier
167 '2147483648', # Signed int32 up frontier
168 '4294967295', # Maximum unsigned int32
170 '9223372036854775807'] # Maximum
172 UINT_VALUES
= ['0', # Minimum
174 '2147483647', # Signed int low frontier
175 '2147483648', # Signed int up frontier
176 '4294967295'] # Maximum
178 INT_VALUES
= ['-2147483648', # Minimum
184 '2147483647'] # Maximum
186 BOOL_VALUES
= ['0', # False
188 # pylint: enable=bad-whitespace,line-too-long,bad-continuation
190 def get_dir_name(ver
, test_type
):
191 """Returns the directory name to save tests given a GLSL version and a
195 assert isinstance(ver
, str)
196 assert isinstance(test_type
, str)
197 if ver
.startswith('GL_'):
198 feature_dir
= ver
[3:].lower()
200 feature_dir
= 'glsl-{}.{}'.format(ver
[0], ver
[1:])
202 return os
.path
.join('spec', feature_dir
, test_type
,
206 class TestTuple(object):
207 """A float64 derived and other type derived tuple to generate the
208 needed conversion tests.
212 def float_to_hex(fvalue
):
213 """Returns the hexadecimal representation from a float32 value."""
214 assert isinstance(fvalue
, np
.float32
)
215 return hex(struct
.unpack('<I', struct
.pack('<f', fvalue
))[0])
218 def double_to_hex(fvalue
):
219 """Returns the hexadecimal representation from a float64 value."""
220 assert isinstance(fvalue
, float)
221 return hex(struct
.unpack('<Q', struct
.pack('<d', fvalue
))[0]).rstrip("L")
224 def hex_to_float(hstr
):
225 """Returns a float32 value from its hexadecimal representation."""
226 assert isinstance(hstr
, str)
227 return struct
.unpack('<f', struct
.pack('<I', int(hstr
, 16)))[0]
230 def hex_to_double(hstr
):
231 """Returns a float64 value from its hexadecimal representation."""
233 assert isinstance(hstr
, str)
234 return struct
.unpack('<d', struct
.pack('<Q', int(hstr
, 16)))[0]
237 def float_hex_to_double_hex(hstr
):
238 """Returns the float64 hexadecimal representation from a float32
239 hexadecimal representation.
241 assert isinstance(hstr
, str)
242 double_value
= TestTuple
.hex_to_float(hstr
)
243 return TestTuple
.double_to_hex(double_value
)
246 def float_hex_to_inv_double_hex(hstr
):
247 """Returns the inverted float64 hexadecimal representation from a
248 float32 hexadecimal representation.
250 assert isinstance(hstr
, str)
251 temp
= TestTuple
.hex_to_float(hstr
)
252 double_value
= np
.divide(1.0, temp
)
253 return TestTuple
.double_to_hex(double_value
)
256 def float_hex_to_int64_str(hstr
):
257 """Returns the int64 string representation from a float32
258 hexadecimal representation.
260 assert isinstance(hstr
, str)
261 x
= TestTuple
.hex_to_float(hstr
)
262 if x
> np
.iinfo(np
.dtype('int64')).max:
263 return str(np
.iinfo(np
.dtype('int64')).max)
264 if x
< np
.iinfo(np
.dtype('int64')).min:
265 return str(np
.iinfo(np
.dtype('int64')).min)
269 def float_hex_to_uint64_str(hstr
):
270 """Returns the uint64 string representation from a float32
271 hexadecimal representation.
273 assert isinstance(hstr
, str)
274 x
= TestTuple
.hex_to_float(hstr
)
275 if x
> np
.iinfo(np
.dtype('uint64')).max:
276 return str(np
.iinfo(np
.dtype('uint64')).max)
277 if x
< np
.iinfo(np
.dtype('uint64')).min:
278 return str(np
.iinfo(np
.dtype('uint64')).min)
282 def int_str_to_bool_str(istr
):
283 """Returns a bool/integer string from an (arbitrary size) integet string."""
284 assert isinstance(istr
, str)
285 return str(int(bool(int(istr
))))
288 def int_str_to_float_hex(istr
):
289 """Returns a float32 hexadecimal representation from an (arbitrary size) integer string."""
290 assert isinstance(istr
, str)
291 return TestTuple
.float_to_hex(np
.float32(int(istr
)))
294 def int_str_to_double_hex(istr
):
295 """Returns a float64 hexadecimal representation from an (arbitrary size) integer string."""
296 assert isinstance(istr
, str)
297 return TestTuple
.double_to_hex(float(istr
))
300 def int_str_to_double_str(istr
):
301 """Returns a float64 string from an (arbitrary size) integer string."""
302 assert isinstance(istr
, str)
303 return str(float(istr
))
306 def int_str_to_int32_str(istr
):
307 """Returns an int32 string from an (arbitrary size) integer string."""
308 x
= int(istr
) & (2**32 - 1)
314 def int_str_to_uint32_str(istr
):
315 """Returns an uint32 string from an (arbitrary size) integer string."""
316 x
= int(istr
) & (2**32 - 1)
320 def int_str_to_int64_str(istr
):
321 """Returns an int64 string from an (arbitrary size) integer string."""
322 x
= int(istr
) & (2**64 - 1)
328 def int_str_to_uint64_str(istr
):
329 """Returns an uint64 string from an (arbitrary size) integer string."""
330 x
= int(istr
) & (2**64 - 1)
334 def int_str_to_type_str(target_type
):
335 """Returns a function for converting an int string to a string for the given type."""
336 assert target_type
in ('d', 'i64', 'u64')
337 if target_type
== 'd':
338 return TestTuple
.int_str_to_double_str
339 elif target_type
== 'i64':
340 return TestTuple
.int_str_to_int64_str
341 elif target_type
== 'u64':
342 return TestTuple
.int_str_to_uint64_str
345 def double_hex_to_bool_str(hstr
):
346 """Returns a bool string from a float64 hexadecimal representation."""
347 assert isinstance(hstr
, str)
348 bool_double
= TestTuple
.hex_to_double(hstr
)
349 return '1' if bool_double
!= 0.0 else '0'
352 def double_hex_to_int_str(hstr
):
353 """Returns an int32 string from a float64 hexadecimal
356 assert isinstance(hstr
, str)
357 int_double
= TestTuple
.hex_to_double(hstr
)
358 if int_double
> np
.iinfo(np
.dtype('int32')).max:
359 return str(np
.iinfo(np
.dtype('int32')).max)
360 if int_double
< np
.iinfo(np
.dtype('int32')).min:
361 return str(np
.iinfo(np
.dtype('int32')).min)
362 return str(int(int_double
))
365 def double_hex_to_uint_str(hstr
):
366 """Returns an uint32 string from a float64 hexadecimal
369 assert isinstance(hstr
, str)
370 uint_double
= TestTuple
.hex_to_double(hstr
)
371 if uint_double
> np
.iinfo(np
.dtype('uint32')).max:
372 return str(np
.iinfo(np
.dtype('uint32')).max)
373 if uint_double
< np
.iinfo(np
.dtype('uint32')).min:
374 return str(np
.iinfo(np
.dtype('uint32')).min)
375 return str(int(uint_double
))
378 def double_hex_to_float_hex(hstr
):
379 """Returns the float32 hexadecimal representation from a float64
380 hexadecimal representation.
382 assert isinstance(hstr
, str)
383 float_double
= np
.float32(TestTuple
.hex_to_double(hstr
))
384 return TestTuple
.float_to_hex(float_double
)
387 def double_hex_to_inv_float_hex(hstr
):
388 """Returns the inverted float32 hexadecimal representation from a
389 float64 hexadecimal representation.
391 assert isinstance(hstr
, str)
392 temp
= np
.divide(1.0, TestTuple
.hex_to_double(hstr
))
393 float_double
= np
.float32(temp
)
394 return TestTuple
.float_to_hex(float_double
)
397 def double_hex_to_int64_str(hstr
):
398 """Returns the int64 string representation from a float64
399 hexadecimal representation.
401 assert isinstance(hstr
, str)
402 x
= TestTuple
.hex_to_double(hstr
)
403 if x
> np
.iinfo(np
.dtype('int64')).max:
404 return str(np
.iinfo(np
.dtype('int64')).max)
405 if x
< np
.iinfo(np
.dtype('int64')).min:
406 return str(np
.iinfo(np
.dtype('int64')).min)
410 def double_hex_to_uint64_str(hstr
):
411 """Returns the uint64 string representation from a float64
412 hexadecimal representation.
414 assert isinstance(hstr
, str)
415 x
= TestTuple
.hex_to_double(hstr
)
416 if x
> np
.iinfo(np
.dtype('uint64')).max:
417 return str(np
.iinfo(np
.dtype('uint64')).max)
418 if x
< np
.iinfo(np
.dtype('uint64')).min:
419 return str(np
.iinfo(np
.dtype('uint64')).min)
422 def __init__(self
, ver
, stage
,
423 first_dimension
, second_dimension
,
424 basic_type
, target_type
, names_only
):
425 assert stage
in ('vert', 'geom', 'frag')
426 assert first_dimension
in ('1', '2', '3', '4')
427 assert second_dimension
in ('1', '2', '3', '4')
428 assert isinstance(names_only
, bool)
432 self
._basic
_type
= basic_type
433 self
._target
_type
= target_type
434 self
._names
_only
= names_only
435 self
._target
_full
_type
= ''
436 self
._conversion
_type
= ''
437 self
._uniform
_type
= ''
438 self
._amount
= int(first_dimension
) * int(second_dimension
)
440 self
._extensions
= []
442 if ver
.startswith('GL_'):
443 if basic_type
== 'd' or target_type
== 'd':
444 self
._extensions
.append('GL_ARB_gpu_shader_fp64')
445 if basic_type
in ('i64', 'u64') or target_type
in ('i64', 'u64'):
446 self
._extensions
.append('GL_ARB_gpu_shader_int64')
448 if first_dimension
!= '1':
449 dimensional_type
= 'mat' + first_dimension
450 if first_dimension
!= second_dimension
:
451 dimensional_type
+= 'x' + second_dimension
452 elif second_dimension
!= '1':
453 dimensional_type
= 'vec' + second_dimension
455 dimensional_type
= ''
457 if dimensional_type
== '':
458 if basic_type
== 'b':
459 self
._conversion
_type
= 'bool'
460 self
._uniform
_type
= 'int'
461 elif basic_type
== 'i':
462 self
._conversion
_type
= 'int'
463 elif basic_type
== 'u':
464 self
._conversion
_type
= 'uint'
465 elif basic_type
== 'f':
466 self
._conversion
_type
= 'float'
467 elif basic_type
== 'd':
468 self
._conversion
_type
= 'double'
469 elif basic_type
== 'i64':
470 self
._conversion
_type
= 'int64_t'
471 elif basic_type
== 'u64':
472 self
._conversion
_type
= 'uint64_t'
473 if self
._uniform
_type
== '':
474 self
._uniform
_type
= self
._conversion
_type
475 if target_type
== 'd':
476 self
._target
_full
_type
= 'double'
477 elif target_type
== 'i64':
478 self
._target
_full
_type
= 'int64_t'
479 elif target_type
== 'u64':
480 self
._target
_full
_type
= 'uint64_t'
482 self
._conversion
_type
= (basic_type
if basic_type
!= 'f' else '') + dimensional_type
483 if basic_type
== 'b':
484 self
._uniform
_type
= 'i' + dimensional_type
486 self
._uniform
_type
= self
._conversion
_type
487 self
._target
_full
_type
= target_type
+ dimensional_type
490 def _gen_to_target(self
):
491 """Generates the test files for conversions to float64."""
494 def _gen_from_target(self
):
495 """Generates the test files for conversions from float64."""
499 """Returns the test file names this tuple will generate."""
500 if self
._filenames
== []:
501 tmp
= self
._names
_only
502 self
._names
_only
= True
503 self
.generate_test_files()
504 self
._names
_only
= tmp
505 return self
._filenames
507 def generate_test_files(self
):
508 """Generate the GLSL parser tests."""
511 self
._gen
_to
_target
()
512 self
._gen
_from
_target
()
515 class RegularTestTuple(TestTuple
):
516 """Derived class for conversion tests using regular values within the
517 edges of the used types.
521 def all_tests(names_only
):
522 """Returns all the possible contained conversion test instances."""
524 assert isinstance(names_only
, bool)
525 stages
= ['vert', 'geom', 'frag']
526 dimensions
= ['1', '2', '3', '4']
527 basic_types
= ['b', 'u', 'i', 'f', 'd', 'i64', 'u64']
528 target_types
= ['d', 'i64', 'u64']
529 glsl_ver
= ['GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400']
532 test_types
= ['compiler', 'execution']
533 for ver
, test_type
in itertools
.product(glsl_ver
, test_types
):
534 utils
.safe_makedirs(get_dir_name(ver
, test_type
))
536 for ver
, stage
, first_dimension
, second_dimension
, basic_type
, target_type
in itertools
.product(
543 has_int64
= basic_type
in ('i64', 'u64') or target_type
in ('i64', 'u64')
544 if (not (first_dimension
!= '1' and
545 (second_dimension
== '1' or basic_type
not in ('f', 'd') or target_type
!= 'd')) and
546 (basic_type
not in target_types
or basic_type
< target_type
) and
547 ((ver
== 'GL_ARB_gpu_shader_int64') == has_int64
)):
548 yield RegularTestTuple(ver
, stage
,
549 first_dimension
, second_dimension
,
550 basic_type
, target_type
, names_only
)
552 def __init__(self
, ver
, stage
,
553 first_dimension
, second_dimension
,
554 basic_type
, target_type
, names_only
):
555 assert ver
in ('GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400')
556 assert basic_type
in ('b', 'u', 'i', 'f', 'd', 'i64', 'u64')
557 assert target_type
in ('d', 'i64', 'u64')
558 assert not (first_dimension
!= '1' and
559 (second_dimension
== '1' or basic_type
not in ('f', 'd') or target_type
!= 'd'))
560 super(RegularTestTuple
, self
).__init
__(ver
, stage
,
561 first_dimension
, second_dimension
,
562 basic_type
, target_type
, names_only
)
564 def _gen_comp_test(self
, from_type
, to_type
, converted_from
):
565 filename
= os
.path
.join(
566 get_dir_name(self
._ver
, 'compiler'),
567 '{}-conversion-implicit-{}-{}-bad.{}'.format(self
._stage
, from_type
, to_type
,
570 self
._filenames
.append(filename
)
572 if not self
._names
_only
:
573 with
open(filename
, 'w') as test_file
:
574 test_file
.write(TEMPLATES
.get_template(
575 'compiler.{}.mako'.format(self
._stage
)).render_unicode(
577 extensions
=self
._extensions
,
580 converted_from
=converted_from
))
582 def _gen_exec_test(self
, from_type
, to_type
,
583 uniform_from_type
, uniform_to_type
,
584 explicit
, converted_from
, conversions
):
585 filename
= os
.path
.join(
586 get_dir_name(self
._ver
, 'execution'),
587 '{}-conversion-{}-{}-{}.shader_test'.format(self
._stage
, explicit
,
590 self
._filenames
.append(filename
)
592 if not self
._names
_only
:
593 with
open(filename
, 'w') as test_file
:
594 test_file
.write(TEMPLATES
.get_template(
595 'execution.{}.shader_test.mako'.format(self
._stage
)).render_unicode(
597 extensions
=self
._extensions
,
601 converted_from
=converted_from
,
602 uniform_from_type
=uniform_from_type
,
603 uniform_to_type
=uniform_to_type
,
604 conversions
=conversions
))
606 def _gen_to_target(self
):
607 converted_from
= 'from'
608 explicit
= 'implicit'
610 if self
._basic
_type
== 'b':
611 conversion_values
= BOOL_VALUES
612 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
613 elif self
._basic
_type
== 'i':
614 conversion_values
= INT_VALUES
615 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
616 elif self
._basic
_type
== 'u':
617 conversion_values
= UINT_VALUES
618 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
619 elif self
._basic
_type
== 'f':
620 if self
._target
_type
== 'd':
621 conversion_values
= FLOAT_INFS
+ FLOAT_NEG_ZERO
+ FLOAT_POS_ZERO
+ FLOAT_VALUES
622 conversion_function
= TestTuple
.float_hex_to_double_hex
623 elif self
._target
_type
== 'i64':
624 conversion_values
= FLOAT_POS_ZERO
+ FLOAT_INT64_VALUES
625 conversion_function
= TestTuple
.float_hex_to_int64_str
626 elif self
._target
_type
== 'u64':
627 conversion_values
= FLOAT_POS_ZERO
+ FLOAT_UINT64_VALUES
628 conversion_function
= TestTuple
.float_hex_to_uint64_str
629 elif self
._basic
_type
== 'd':
630 if self
._target
_type
== 'i64':
631 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_INT_VALUES
632 conversion_function
= TestTuple
.double_hex_to_int64_str
633 elif self
._target
_type
== 'u64':
634 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_UINT_VALUES
635 conversion_function
= TestTuple
.double_hex_to_uint64_str
636 elif self
._basic
_type
in ('i64', 'u64'):
637 if self
._basic
_type
== 'i64':
638 conversion_values
= INT64_VALUES
640 conversion_values
= UINT64_VALUES
641 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
643 if (self
._basic
_type
== 'b' or
644 (self
._basic
_type
in ('f', 'd') and self
._target
_type
in ('i64', 'u64')) or
645 (self
._basic
_type
== 'u' and self
._target
_type
== 'i64')):
646 explicit
= 'explicit'
647 self
._gen
_comp
_test
(self
._conversion
_type
, self
._target
_full
_type
,
649 converted_from
= self
._target
_full
_type
+ '(from)'
652 for value
in conversion_values
:
653 to_value
= conversion_function(value
)
654 item
= {'from': value
, 'to': to_value
}
655 conversions
.append(item
)
657 self
._gen
_exec
_test
(self
._conversion
_type
, self
._target
_full
_type
,
658 self
._uniform
_type
, self
._target
_full
_type
,
659 explicit
, converted_from
, conversions
)
661 def _gen_from_target(self
):
662 converted_from
= 'from'
663 explicit
= 'implicit'
665 if self
._target
_type
== 'd':
666 if self
._basic
_type
== 'b':
667 conversion_values
= DOUBLE_INFS
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_BOOL_VALUES
668 conversion_function
= TestTuple
.double_hex_to_bool_str
669 elif self
._basic
_type
== 'i':
670 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_INT_VALUES
671 conversion_function
= TestTuple
.double_hex_to_int_str
672 elif self
._basic
_type
== 'u':
673 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_UINT_VALUES
674 conversion_function
= TestTuple
.double_hex_to_uint_str
675 elif self
._basic
_type
== 'f':
676 conversion_values
= DOUBLE_INFS
+ DOUBLE_FLOAT_INFS
+ DOUBLE_FLOAT_VALUES
677 conversion_function
= TestTuple
.double_hex_to_float_hex
678 conversion_values
= DOUBLE_NEG_ZERO
+ DOUBLE_POS_ZERO
+ conversion_values
679 elif self
._target
_type
in ('i64', 'u64'):
680 if self
._target
_type
== 'i64':
681 conversion_values
= INT64_VALUES
682 elif self
._target
_type
== 'u64':
683 conversion_values
= UINT64_VALUES
685 if self
._basic
_type
== 'b':
686 conversion_function
= TestTuple
.int_str_to_bool_str
687 elif self
._basic
_type
== 'i':
688 conversion_function
= TestTuple
.int_str_to_int32_str
689 elif self
._basic
_type
== 'u':
690 conversion_function
= TestTuple
.int_str_to_uint32_str
691 elif self
._basic
_type
== 'f':
692 conversion_function
= TestTuple
.int_str_to_float_hex
693 elif self
._basic
_type
== 'd':
694 conversion_function
= TestTuple
.int_str_to_double_hex
695 elif self
._basic
_type
== 'i64':
696 conversion_function
= TestTuple
.int_str_to_int64_str
697 elif self
._basic
_type
== 'i':
698 conversion_function
= TestTuple
.int_str_to_uint64_str
700 if self
._basic
_type
!= 'd':
701 self
._gen
_comp
_test
(self
._target
_full
_type
, self
._conversion
_type
,
704 converted_from
= self
._conversion
_type
+ '(from)'
705 explicit
= 'explicit'
707 assert self
._target
_type
in ('i64', 'u64')
710 for value
in conversion_values
:
711 to_value
= conversion_function(value
)
712 item
= {'from': value
, 'to': to_value
}
713 conversions
.append(item
)
715 self
._gen
_exec
_test
(self
._target
_full
_type
, self
._conversion
_type
,
716 self
._target
_full
_type
, self
._uniform
_type
,
717 explicit
, converted_from
, conversions
)
720 class ZeroSignTestTuple(TestTuple
):
721 """Derived class for conversion tests using the float32 and float64
726 def all_tests(names_only
):
727 """Returns all the possible zero sign conversion test instances."""
729 assert isinstance(names_only
, bool)
730 stages
= ['vert', 'geom', 'frag']
731 dimensions
= ['1', '2', '3', '4']
733 glsl_ver
= ['410', '420']
737 utils
.safe_makedirs(get_dir_name(ver
, 'execution'))
739 for ver
, stage
, first_dimension
, second_dimension
, basic_type
in itertools
.product(
745 if not (first_dimension
!= '1' and second_dimension
== '1'):
746 yield ZeroSignTestTuple(ver
, stage
,
747 first_dimension
, second_dimension
,
748 basic_type
, names_only
)
750 def __init__(self
, ver
, stage
,
751 first_dimension
, second_dimension
,
752 basic_type
, names_only
):
753 assert ver
in ('410', '420')
754 assert basic_type
== 'f'
755 assert not (first_dimension
!= '1' and second_dimension
== '1')
756 super(ZeroSignTestTuple
, self
).__init
__(ver
, stage
,
757 first_dimension
, second_dimension
,
758 basic_type
, 'd', names_only
)
760 def __gen_zero_sign_exec_test(self
, from_type
, to_type
,
761 uniform_from_type
, uniform_to_type
,
762 explicit
, converted_from
, conversions
):
763 filename
= os
.path
.join(
764 get_dir_name(self
._ver
, 'execution'),
765 '{}-conversion-{}-{}-{}-zero-sign.shader_test'.format(self
._stage
, explicit
,
768 self
._filenames
.append(filename
)
770 if not self
._names
_only
:
771 with
open(filename
, 'w') as test_file
:
772 test_file
.write(TEMPLATES
.get_template(
773 'execution-zero-sign.{}.shader_test.mako'.format(
774 self
._stage
)).render_unicode(
776 extensions
=self
._extensions
,
780 converted_from
=converted_from
,
781 uniform_from_type
=uniform_from_type
,
782 uniform_to_type
=uniform_to_type
,
783 conversions
=conversions
))
785 def _gen_to_target(self
):
786 if self
._ver
== '410':
787 conversion_values
= FLOAT_POS_ZERO
788 elif self
._ver
== '420':
789 conversion_values
= FLOAT_NEG_ZERO
792 for value
in conversion_values
:
793 to_value
= TestTuple
.float_hex_to_inv_double_hex(value
)
794 item
= {'from': value
, 'to': to_value
}
795 conversions
.append(item
)
797 self
.__gen
_zero
_sign
_exec
_test
(self
._conversion
_type
, self
._target
_full
_type
,
798 self
._uniform
_type
, self
._target
_full
_type
,
799 'implicit', 'from', conversions
)
801 def _gen_from_target(self
):
802 if self
._ver
== '410':
803 conversion_values
= DOUBLE_POS_ZERO
804 elif self
._ver
== '420':
805 conversion_values
= DOUBLE_NEG_ZERO
808 for value
in conversion_values
:
809 to_value
= TestTuple
.double_hex_to_inv_float_hex(value
)
810 item
= {'from': value
, 'to': to_value
}
811 conversions
.append(item
)
813 self
.__gen
_zero
_sign
_exec
_test
(self
._target
_full
_type
, self
._conversion
_type
,
814 self
._target
_full
_type
, self
._uniform
_type
,
815 'explicit', self
._conversion
_type
+ '(from)', conversions
)
821 parser
= argparse
.ArgumentParser(
822 description
="Generate shader tests that check the conversions from and "
829 help="Don't output files, just generate a list of filenames to stdout")
830 args
= parser
.parse_args()
832 np
.seterr(divide
='ignore')
834 for test
in (list(RegularTestTuple
.all_tests(args
.names_only
)) +
835 list(ZeroSignTestTuple
.all_tests(args
.names_only
))):
836 test
.generate_test_files()
837 for filename
in test
.filenames
:
841 if __name__
== '__main__':