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."""
34 from templates
import template_dir
35 from modules
import utils
37 TEMPLATES
= template_dir(os
.path
.basename(os
.path
.splitext(__file__
)[0]))
39 # pylint: disable=bad-whitespace,line-too-long,bad-continuation
40 DOUBLE_INFS
= ['0xfff0000000000000', # -inf
41 '0x7ff0000000000000'] # +inf
43 DOUBLE_NEG_ZERO
= ['0x8000000000000000'] # Negative underflow (-0.0)
45 DOUBLE_POS_ZERO
= ['0x0000000000000000'] # Positive underflow (+0.0)
47 # Double values causing an underflow to zero in any other type
48 DOUBLE_DENORMAL_VALUES
= ['0x800fffffffffffff', # Negative maximum denormalized -- Denormalized may be flushed to 0
49 '0x8000000000000001', # Negative minimum denormalized -- Denormalized may be flushed to 0
50 '0x0000000000000001', # Positive minimum denormalized -- Denormalized may be flushed to 0
51 '0x000fffffffffffff'] # Positive maximum denormalized -- Denormalized may be flushed to 0
53 DOUBLE_NORMAL_VALUES
= ['0x8010000000000000', # Negative minimum normalized
54 '0x0010000000000000'] # Positive minimum normalized
57 DOUBLE_FLOAT_INFS
= ['0xc7effffff0000000', # Negative overflow (-inf)
58 '0x47effffff0000000'] # Positive overflow (+inf)
60 DOUBLE_FLOAT_VALUES
= ['0xc7efffffefffffff', # Negative maximum normalized
61 '0xc170000000000000', # -16777216.0
62 '0xc014000000000000', # -5.0
63 '0xbfff25ce60000000', # -1.9467300176620483
64 '0xb80fffffe0000000', # Negative minimum normalized
65 '0xb69fffffffffffff', # Negative underflow
66 '0x369fffffffffffff', # Positive underflow
67 '0x380fffffe0000000', # Positive minimum normalized
68 '0x3fff25ce60000000', # +1.9467300176620483
69 '0x4014000000000000', # +5.0
70 '0x4170000000000000', # +16777216.0
71 '0x47efffffefffffff'] # Positive maximum normalized
73 DOUBLE_UINT_VALUES
= ['0xbfeccccccccccccd', # -0.9
74 #'0x8010000000000000', # Negative minimum normalized -- Already checked
75 #'0x800fffffffffffff', # Negative maximum denormalized -- Already checked
76 #'0x8000000000000001', # Negative minimum denormalized -- Already checked
77 #'0x8000000000000000', # Negative minimum (-0) -- Already checked
78 #'0x0000000000000000', # Positive minimum (+0) -- Already checked
79 '0x3fff25ce60000000', # +1.9467300176620483
80 '0x4014000000000000', # +5.0
81 '0x4170000000000000', # +16777216.0
82 '0x41dfffffffc00000', # Signed int low frontier (+2147483647)
83 '0x41e0000000000000', # Signed int up frontier (+2147483648)
84 '0x41efffffffe00000'] # Maximum (+4294967295)
86 DOUBLE_INT_VALUES
= ['0xc1e0000000000000', # Minimum (-2147483648)
87 '0xc170000000000000', # -16777216.0
88 '0xc014000000000000', # -5.0
89 '0xbfff25ce60000000', # -1.9467300176620483
90 #'0x8000000000000000', # Negative minimum (-0) -- Already checked
91 #'0x0000000000000000', # Minimum (+0) -- Already checked
92 '0x3fff25ce60000000', # +1.9467300176620483
93 '0x4014000000000000', # +5.0
94 '0x4170000000000000', # +16777216.0
95 '0x41dfffffffc00000'] # Maximum (+2147483647)
97 DOUBLE_BOOL_VALUES
= [#'0x8010000000000000', # Minimum negative True value -- Already checked
98 #'0x0000000000000000', # False -- Already checked
99 #'0x0010000000000000', # Minimum positive True value -- Already checked
102 FLOAT_INFS
= ['0xff800000', # -inf
105 FLOAT_NEG_ZERO
= ['0x80000000'] # Negative underflow (-0.0)
107 FLOAT_POS_ZERO
= ['0x00000000'] # Positive underflow (+0.0)
109 FLOAT_VALUES
= ['0xff7fffff', # Negative maximum normalized
110 '0xcb800000', # -16777216.0
112 '0xbff92e73', # -1.9467300176620483
113 '0x80800000', # Negative minimum normalized
114 #'0x807fffff', # Negative maximum denormalized -- Denormalized may be flushed to 0
115 #'0x80000001', # Negative minimum denormalized -- Denormalized may be flushed to 0
116 #'0x00000001', # Positive minimum denormalized -- Denormalized may be flushed to 0
117 #'0x007fffff', # Positive maximum denormalized -- Denormalized may be flushed to 0
118 '0x00800000', # Positive minimum normalized
119 '0x3ff92e73', # +1.9467300176620483
121 '0x4b800000', # +16777216.0
122 '0x7f7fffff'] # Positive maximum normalized
124 FLOAT_INT64_VALUES
= ['0xcf800000', # -4294967296.0
125 '0xcb800000', # -16777216.0
127 '0xbff92e73', # -1.9467300176620483
128 '0x80800000', # Negative minimum normalized
129 '0x807fffff', # Negative maximum denormalized
130 '0x80000001', # Negative minimum denormalized
131 '0x00000001', # Positive minimum denormalized
132 '0x007fffff', # Positive maximum denormalized
133 '0x00800000', # Positive minimum normalized
134 '0x3ff92e73', # +1.9467300176620483
136 '0x4b800000', # +16777216.0
137 '0x4f800000'] # +4294967296.0
139 FLOAT_UINT64_VALUES
= ['0x00000001', # Positive minimum denormalized
140 '0x007fffff', # Positive maximum denormalized
141 '0x00800000', # Positive minimum normalized
142 '0x3ff92e73', # +1.9467300176620483
144 '0x4b800000', # +16777216.0
145 '0x4f800000'] # +4294967296.0
147 UINT64_VALUES
= ['0', # Minimum
149 '2147483647', # Signed int32 low frontier
150 '2147483648', # Signed int32 up frontier
151 '4294967295', # Maximum unsigned int32
153 '9223372036854775807', # Signed int64 low frontier
154 '9223372036854775808', # Signed int64 up frontier
155 '18446744073709551615'] # Maximum
157 INT64_VALUES
= ['-9223372036854775808', # Minimum
165 '2147483647', # Signed int32 low frontier
166 '2147483648', # Signed int32 up frontier
167 '4294967295', # Maximum unsigned int32
169 '9223372036854775807'] # Maximum
171 UINT_VALUES
= ['0', # Minimum
173 '2147483647', # Signed int low frontier
174 '2147483648', # Signed int up frontier
175 '4294967295'] # Maximum
177 INT_VALUES
= ['-2147483648', # Minimum
183 '2147483647'] # Maximum
185 BOOL_VALUES
= ['0', # False
187 # pylint: enable=bad-whitespace,line-too-long,bad-continuation
189 def get_dir_name(ver
, test_type
):
190 """Returns the directory name to save tests given a GLSL version and a
194 assert isinstance(ver
, str)
195 assert isinstance(test_type
, str)
196 if ver
.startswith('GL_'):
197 feature_dir
= ver
[3:].lower()
199 feature_dir
= 'glsl-{}.{}'.format(ver
[0], ver
[1:])
201 return os
.path
.join('spec', feature_dir
, test_type
,
205 class TestTuple(object):
206 """A float64 derived and other type derived tuple to generate the
207 needed conversion tests.
211 def float_to_hex(fvalue
):
212 """Returns the hexadecimal representation from a float32 value."""
213 assert isinstance(fvalue
, np
.float32
)
214 return hex(struct
.unpack('<I', struct
.pack('<f', fvalue
))[0])
217 def double_to_hex(fvalue
):
218 """Returns the hexadecimal representation from a float64 value."""
219 assert isinstance(fvalue
, float)
220 return hex(struct
.unpack('<Q', struct
.pack('<d', fvalue
))[0]).rstrip("L")
223 def hex_to_float(hstr
):
224 """Returns a float32 value from its hexadecimal representation."""
225 assert isinstance(hstr
, str)
226 return struct
.unpack('<f', struct
.pack('<I', int(hstr
, 16)))[0]
229 def hex_to_double(hstr
):
230 """Returns a float64 value from its hexadecimal representation."""
232 assert isinstance(hstr
, str)
233 return struct
.unpack('<d', struct
.pack('<Q', int(hstr
, 16)))[0]
236 def float_hex_to_double_hex(hstr
):
237 """Returns the float64 hexadecimal representation from a float32
238 hexadecimal representation.
240 assert isinstance(hstr
, str)
241 double_value
= TestTuple
.hex_to_float(hstr
)
242 return TestTuple
.double_to_hex(double_value
)
245 def float_hex_to_inv_double_hex(hstr
):
246 """Returns the inverted float64 hexadecimal representation from a
247 float32 hexadecimal representation.
249 assert isinstance(hstr
, str)
250 temp
= TestTuple
.hex_to_float(hstr
)
251 double_value
= np
.divide(1.0, temp
)
252 return TestTuple
.double_to_hex(double_value
)
255 def float_hex_to_int64_str(hstr
):
256 """Returns the int64 string representation from a float32
257 hexadecimal representation.
259 assert isinstance(hstr
, str)
260 x
= TestTuple
.hex_to_float(hstr
)
261 if x
> np
.iinfo(np
.dtype('int64')).max:
262 return str(np
.iinfo(np
.dtype('int64')).max)
263 if x
< np
.iinfo(np
.dtype('int64')).min:
264 return str(np
.iinfo(np
.dtype('int64')).min)
268 def float_hex_to_uint64_str(hstr
):
269 """Returns the uint64 string representation from a float32
270 hexadecimal representation.
272 assert isinstance(hstr
, str)
273 x
= TestTuple
.hex_to_float(hstr
)
274 if x
> np
.iinfo(np
.dtype('uint64')).max:
275 return str(np
.iinfo(np
.dtype('uint64')).max)
276 if x
< np
.iinfo(np
.dtype('uint64')).min:
277 return str(np
.iinfo(np
.dtype('uint64')).min)
281 def int_str_to_bool_str(istr
):
282 """Returns a bool/integer string from an (arbitrary size) integet string."""
283 assert isinstance(istr
, str)
284 return str(int(bool(int(istr
))))
287 def int_str_to_float_hex(istr
):
288 """Returns a float32 hexadecimal representation from an (arbitrary size) integer string."""
289 assert isinstance(istr
, str)
290 return TestTuple
.float_to_hex(np
.float32(int(istr
)))
293 def int_str_to_double_hex(istr
):
294 """Returns a float64 hexadecimal representation from an (arbitrary size) integer string."""
295 assert isinstance(istr
, str)
296 return TestTuple
.double_to_hex(float(istr
))
299 def int_str_to_double_str(istr
):
300 """Returns a float64 string from an (arbitrary size) integer string."""
301 assert isinstance(istr
, str)
302 return str(float(istr
))
305 def int_str_to_int32_str(istr
):
306 """Returns an int32 string from an (arbitrary size) integer string."""
307 x
= int(istr
) & (2**32 - 1)
313 def int_str_to_uint32_str(istr
):
314 """Returns an uint32 string from an (arbitrary size) integer string."""
315 x
= int(istr
) & (2**32 - 1)
319 def int_str_to_int64_str(istr
):
320 """Returns an int64 string from an (arbitrary size) integer string."""
321 x
= int(istr
) & (2**64 - 1)
327 def int_str_to_uint64_str(istr
):
328 """Returns an uint64 string from an (arbitrary size) integer string."""
329 x
= int(istr
) & (2**64 - 1)
333 def int_str_to_type_str(target_type
):
334 """Returns a function for converting an int string to a string for the given type."""
335 assert target_type
in ('d', 'i64', 'u64')
336 if target_type
== 'd':
337 return TestTuple
.int_str_to_double_str
338 elif target_type
== 'i64':
339 return TestTuple
.int_str_to_int64_str
340 elif target_type
== 'u64':
341 return TestTuple
.int_str_to_uint64_str
344 def double_hex_to_bool_str(hstr
):
345 """Returns a bool string from a float64 hexadecimal representation."""
346 assert isinstance(hstr
, str)
347 bool_double
= TestTuple
.hex_to_double(hstr
)
348 return '1' if bool_double
!= 0.0 else '0'
351 def double_hex_to_int_str(hstr
):
352 """Returns an int32 string from a float64 hexadecimal
355 assert isinstance(hstr
, str)
356 int_double
= TestTuple
.hex_to_double(hstr
)
357 if int_double
> np
.iinfo(np
.dtype('int32')).max:
358 return str(np
.iinfo(np
.dtype('int32')).max)
359 if int_double
< np
.iinfo(np
.dtype('int32')).min:
360 return str(np
.iinfo(np
.dtype('int32')).min)
361 return str(int(int_double
))
364 def double_hex_to_uint_str(hstr
):
365 """Returns an uint32 string from a float64 hexadecimal
368 assert isinstance(hstr
, str)
369 uint_double
= TestTuple
.hex_to_double(hstr
)
370 if uint_double
> np
.iinfo(np
.dtype('uint32')).max:
371 return str(np
.iinfo(np
.dtype('uint32')).max)
372 if uint_double
< np
.iinfo(np
.dtype('uint32')).min:
373 return str(np
.iinfo(np
.dtype('uint32')).min)
374 return str(int(uint_double
))
377 def double_hex_to_float_hex(hstr
):
378 """Returns the float32 hexadecimal representation from a float64
379 hexadecimal representation.
381 assert isinstance(hstr
, str)
382 float_double
= np
.float32(TestTuple
.hex_to_double(hstr
))
383 return TestTuple
.float_to_hex(float_double
)
386 def double_hex_to_inv_float_hex(hstr
):
387 """Returns the inverted float32 hexadecimal representation from a
388 float64 hexadecimal representation.
390 assert isinstance(hstr
, str)
391 temp
= np
.divide(1.0, TestTuple
.hex_to_double(hstr
))
392 float_double
= np
.float32(temp
)
393 return TestTuple
.float_to_hex(float_double
)
396 def double_hex_to_int64_str(hstr
):
397 """Returns the int64 string representation from a float64
398 hexadecimal representation.
400 assert isinstance(hstr
, str)
401 x
= TestTuple
.hex_to_double(hstr
)
402 if x
> np
.iinfo(np
.dtype('int64')).max:
403 return str(np
.iinfo(np
.dtype('int64')).max)
404 if x
< np
.iinfo(np
.dtype('int64')).min:
405 return str(np
.iinfo(np
.dtype('int64')).min)
409 def double_hex_to_uint64_str(hstr
):
410 """Returns the uint64 string representation from a float64
411 hexadecimal representation.
413 assert isinstance(hstr
, str)
414 x
= TestTuple
.hex_to_double(hstr
)
415 if x
> np
.iinfo(np
.dtype('uint64')).max:
416 return str(np
.iinfo(np
.dtype('uint64')).max)
417 if x
< np
.iinfo(np
.dtype('uint64')).min:
418 return str(np
.iinfo(np
.dtype('uint64')).min)
421 def __init__(self
, ver
, stage
,
422 first_dimension
, second_dimension
,
423 basic_type
, target_type
, names_only
):
424 assert stage
in ('vert', 'geom', 'frag')
425 assert first_dimension
in ('1', '2', '3', '4')
426 assert second_dimension
in ('1', '2', '3', '4')
427 assert isinstance(names_only
, bool)
431 self
._basic
_type
= basic_type
432 self
._target
_type
= target_type
433 self
._names
_only
= names_only
434 self
._target
_full
_type
= ''
435 self
._conversion
_type
= ''
436 self
._uniform
_type
= ''
437 self
._amount
= int(first_dimension
) * int(second_dimension
)
439 self
._extensions
= []
441 if ver
.startswith('GL_'):
442 if basic_type
== 'd' or target_type
== 'd':
443 self
._extensions
.append('GL_ARB_gpu_shader_fp64')
444 if basic_type
in ('i64', 'u64') or target_type
in ('i64', 'u64'):
445 self
._extensions
.append('GL_ARB_gpu_shader_int64')
447 if first_dimension
!= '1':
448 dimensional_type
= 'mat' + first_dimension
449 if first_dimension
!= second_dimension
:
450 dimensional_type
+= 'x' + second_dimension
451 elif second_dimension
!= '1':
452 dimensional_type
= 'vec' + second_dimension
454 dimensional_type
= ''
456 if dimensional_type
== '':
457 if basic_type
== 'b':
458 self
._conversion
_type
= 'bool'
459 self
._uniform
_type
= 'int'
460 elif basic_type
== 'i':
461 self
._conversion
_type
= 'int'
462 elif basic_type
== 'u':
463 self
._conversion
_type
= 'uint'
464 elif basic_type
== 'f':
465 self
._conversion
_type
= 'float'
466 elif basic_type
== 'd':
467 self
._conversion
_type
= 'double'
468 elif basic_type
== 'i64':
469 self
._conversion
_type
= 'int64_t'
470 elif basic_type
== 'u64':
471 self
._conversion
_type
= 'uint64_t'
472 if self
._uniform
_type
== '':
473 self
._uniform
_type
= self
._conversion
_type
474 if target_type
== 'd':
475 self
._target
_full
_type
= 'double'
476 elif target_type
== 'i64':
477 self
._target
_full
_type
= 'int64_t'
478 elif target_type
== 'u64':
479 self
._target
_full
_type
= 'uint64_t'
481 self
._conversion
_type
= (basic_type
if basic_type
!= 'f' else '') + dimensional_type
482 if basic_type
== 'b':
483 self
._uniform
_type
= 'i' + dimensional_type
485 self
._uniform
_type
= self
._conversion
_type
486 self
._target
_full
_type
= target_type
+ dimensional_type
489 def _gen_to_target(self
):
490 """Generates the test files for conversions to float64."""
493 def _gen_from_target(self
):
494 """Generates the test files for conversions from float64."""
498 """Returns the test file names this tuple will generate."""
499 if self
._filenames
== []:
500 tmp
= self
._names
_only
501 self
._names
_only
= True
502 self
.generate_test_files()
503 self
._names
_only
= tmp
504 return self
._filenames
506 def generate_test_files(self
):
507 """Generate the GLSL parser tests."""
510 self
._gen
_to
_target
()
511 self
._gen
_from
_target
()
514 class RegularTestTuple(TestTuple
):
515 """Derived class for conversion tests using regular values within the
516 edges of the used types.
520 def all_tests(names_only
):
521 """Returns all the possible contained conversion test instances."""
523 assert isinstance(names_only
, bool)
524 stages
= ['vert', 'geom', 'frag']
525 dimensions
= ['1', '2', '3', '4']
526 basic_types
= ['b', 'u', 'i', 'f', 'd', 'i64', 'u64']
527 target_types
= ['d', 'i64', 'u64']
528 glsl_ver
= ['GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400']
531 test_types
= ['compiler', 'execution']
532 for ver
, test_type
in itertools
.product(glsl_ver
, test_types
):
533 utils
.safe_makedirs(get_dir_name(ver
, test_type
))
535 for ver
, stage
, first_dimension
, second_dimension
, basic_type
, target_type
in itertools
.product(
542 has_int64
= basic_type
in ('i64', 'u64') or target_type
in ('i64', 'u64')
543 if (not (first_dimension
!= '1' and
544 (second_dimension
== '1' or basic_type
not in ('f', 'd') or target_type
!= 'd')) and
545 (basic_type
not in target_types
or basic_type
< target_type
) and
546 ((ver
== 'GL_ARB_gpu_shader_int64') == has_int64
)):
547 yield RegularTestTuple(ver
, stage
,
548 first_dimension
, second_dimension
,
549 basic_type
, target_type
, names_only
)
551 def __init__(self
, ver
, stage
,
552 first_dimension
, second_dimension
,
553 basic_type
, target_type
, names_only
):
554 assert ver
in ('GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400')
555 assert basic_type
in ('b', 'u', 'i', 'f', 'd', 'i64', 'u64')
556 assert target_type
in ('d', 'i64', 'u64')
557 assert not (first_dimension
!= '1' and
558 (second_dimension
== '1' or basic_type
not in ('f', 'd') or target_type
!= 'd'))
559 super(RegularTestTuple
, self
).__init
__(ver
, stage
,
560 first_dimension
, second_dimension
,
561 basic_type
, target_type
, names_only
)
563 def _gen_comp_test(self
, from_type
, to_type
, converted_from
):
564 filename
= os
.path
.join(
565 get_dir_name(self
._ver
, 'compiler'),
566 '{}-conversion-implicit-{}-{}-bad.{}'.format(self
._stage
, from_type
, to_type
,
569 self
._filenames
.append(filename
)
571 if not self
._names
_only
:
572 with
open(filename
, 'w') as test_file
:
573 test_file
.write(TEMPLATES
.get_template(
574 'compiler.{}.mako'.format(self
._stage
)).render_unicode(
576 extensions
=self
._extensions
,
579 converted_from
=converted_from
))
581 def _gen_exec_test(self
, from_type
, to_type
,
582 uniform_from_type
, uniform_to_type
,
583 explicit
, converted_from
, conversions
):
584 filename
= os
.path
.join(
585 get_dir_name(self
._ver
, 'execution'),
586 '{}-conversion-{}-{}-{}.shader_test'.format(self
._stage
, explicit
,
589 self
._filenames
.append(filename
)
591 if not self
._names
_only
:
592 with
open(filename
, 'w') as test_file
:
593 test_file
.write(TEMPLATES
.get_template(
594 'execution.{}.shader_test.mako'.format(self
._stage
)).render_unicode(
596 extensions
=self
._extensions
,
600 converted_from
=converted_from
,
601 uniform_from_type
=uniform_from_type
,
602 uniform_to_type
=uniform_to_type
,
603 conversions
=conversions
))
605 def _gen_to_target(self
):
606 converted_from
= 'from'
607 explicit
= 'implicit'
609 if self
._basic
_type
== 'b':
610 conversion_values
= BOOL_VALUES
611 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
612 elif self
._basic
_type
== 'i':
613 conversion_values
= INT_VALUES
614 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
615 elif self
._basic
_type
== 'u':
616 conversion_values
= UINT_VALUES
617 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
618 elif self
._basic
_type
== 'f':
619 if self
._target
_type
== 'd':
620 conversion_values
= FLOAT_INFS
+ FLOAT_NEG_ZERO
+ FLOAT_POS_ZERO
+ FLOAT_VALUES
621 conversion_function
= TestTuple
.float_hex_to_double_hex
622 elif self
._target
_type
== 'i64':
623 conversion_values
= FLOAT_POS_ZERO
+ FLOAT_INT64_VALUES
624 conversion_function
= TestTuple
.float_hex_to_int64_str
625 elif self
._target
_type
== 'u64':
626 conversion_values
= FLOAT_POS_ZERO
+ FLOAT_UINT64_VALUES
627 conversion_function
= TestTuple
.float_hex_to_uint64_str
628 elif self
._basic
_type
== 'd':
629 if self
._target
_type
== 'i64':
630 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_INT_VALUES
631 conversion_function
= TestTuple
.double_hex_to_int64_str
632 elif self
._target
_type
== 'u64':
633 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_UINT_VALUES
634 conversion_function
= TestTuple
.double_hex_to_uint64_str
635 elif self
._basic
_type
in ('i64', 'u64'):
636 if self
._basic
_type
== 'i64':
637 conversion_values
= INT64_VALUES
639 conversion_values
= UINT64_VALUES
640 conversion_function
= TestTuple
.int_str_to_type_str(self
._target
_type
)
642 if (self
._basic
_type
== 'b' or
643 (self
._basic
_type
in ('f', 'd') and self
._target
_type
in ('i64', 'u64')) or
644 (self
._basic
_type
== 'u' and self
._target
_type
== 'i64')):
645 explicit
= 'explicit'
646 self
._gen
_comp
_test
(self
._conversion
_type
, self
._target
_full
_type
,
648 converted_from
= self
._target
_full
_type
+ '(from)'
651 for value
in conversion_values
:
652 to_value
= conversion_function(value
)
653 item
= {'from': value
, 'to': to_value
}
654 conversions
.append(item
)
656 self
._gen
_exec
_test
(self
._conversion
_type
, self
._target
_full
_type
,
657 self
._uniform
_type
, self
._target
_full
_type
,
658 explicit
, converted_from
, conversions
)
660 def _gen_from_target(self
):
661 converted_from
= 'from'
662 explicit
= 'implicit'
664 if self
._target
_type
== 'd':
665 if self
._basic
_type
== 'b':
666 conversion_values
= DOUBLE_INFS
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_BOOL_VALUES
667 conversion_function
= TestTuple
.double_hex_to_bool_str
668 elif self
._basic
_type
== 'i':
669 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_INT_VALUES
670 conversion_function
= TestTuple
.double_hex_to_int_str
671 elif self
._basic
_type
== 'u':
672 conversion_values
= DOUBLE_DENORMAL_VALUES
+ DOUBLE_NORMAL_VALUES
+ DOUBLE_UINT_VALUES
673 conversion_function
= TestTuple
.double_hex_to_uint_str
674 elif self
._basic
_type
== 'f':
675 conversion_values
= DOUBLE_INFS
+ DOUBLE_FLOAT_INFS
+ DOUBLE_FLOAT_VALUES
676 conversion_function
= TestTuple
.double_hex_to_float_hex
677 conversion_values
= DOUBLE_NEG_ZERO
+ DOUBLE_POS_ZERO
+ conversion_values
678 elif self
._target
_type
in ('i64', 'u64'):
679 if self
._target
_type
== 'i64':
680 conversion_values
= INT64_VALUES
681 elif self
._target
_type
== 'u64':
682 conversion_values
= UINT64_VALUES
684 if self
._basic
_type
== 'b':
685 conversion_function
= TestTuple
.int_str_to_bool_str
686 elif self
._basic
_type
== 'i':
687 conversion_function
= TestTuple
.int_str_to_int32_str
688 elif self
._basic
_type
== 'u':
689 conversion_function
= TestTuple
.int_str_to_uint32_str
690 elif self
._basic
_type
== 'f':
691 conversion_function
= TestTuple
.int_str_to_float_hex
692 elif self
._basic
_type
== 'd':
693 conversion_function
= TestTuple
.int_str_to_double_hex
694 elif self
._basic
_type
== 'i64':
695 conversion_function
= TestTuple
.int_str_to_int64_str
696 elif self
._basic
_type
== 'i':
697 conversion_function
= TestTuple
.int_str_to_uint64_str
699 if self
._basic
_type
!= 'd':
700 self
._gen
_comp
_test
(self
._target
_full
_type
, self
._conversion
_type
,
703 converted_from
= self
._conversion
_type
+ '(from)'
704 explicit
= 'explicit'
706 assert self
._target
_type
in ('i64', 'u64')
709 for value
in conversion_values
:
710 to_value
= conversion_function(value
)
711 item
= {'from': value
, 'to': to_value
}
712 conversions
.append(item
)
714 self
._gen
_exec
_test
(self
._target
_full
_type
, self
._conversion
_type
,
715 self
._target
_full
_type
, self
._uniform
_type
,
716 explicit
, converted_from
, conversions
)
719 class ZeroSignTestTuple(TestTuple
):
720 """Derived class for conversion tests using the float32 and float64
725 def all_tests(names_only
):
726 """Returns all the possible zero sign conversion test instances."""
728 assert isinstance(names_only
, bool)
729 stages
= ['vert', 'geom', 'frag']
730 dimensions
= ['1', '2', '3', '4']
732 glsl_ver
= ['410', '420']
736 utils
.safe_makedirs(get_dir_name(ver
, 'execution'))
738 for ver
, stage
, first_dimension
, second_dimension
, basic_type
in itertools
.product(
744 if not (first_dimension
!= '1' and second_dimension
== '1'):
745 yield ZeroSignTestTuple(ver
, stage
,
746 first_dimension
, second_dimension
,
747 basic_type
, names_only
)
749 def __init__(self
, ver
, stage
,
750 first_dimension
, second_dimension
,
751 basic_type
, names_only
):
752 assert ver
in ('410', '420')
753 assert basic_type
== 'f'
754 assert not (first_dimension
!= '1' and second_dimension
== '1')
755 super(ZeroSignTestTuple
, self
).__init
__(ver
, stage
,
756 first_dimension
, second_dimension
,
757 basic_type
, 'd', names_only
)
759 def __gen_zero_sign_exec_test(self
, from_type
, to_type
,
760 uniform_from_type
, uniform_to_type
,
761 explicit
, converted_from
, conversions
):
762 filename
= os
.path
.join(
763 get_dir_name(self
._ver
, 'execution'),
764 '{}-conversion-{}-{}-{}-zero-sign.shader_test'.format(self
._stage
, explicit
,
767 self
._filenames
.append(filename
)
769 if not self
._names
_only
:
770 with
open(filename
, 'w') as test_file
:
771 test_file
.write(TEMPLATES
.get_template(
772 'execution-zero-sign.{}.shader_test.mako'.format(
773 self
._stage
)).render_unicode(
775 extensions
=self
._extensions
,
779 converted_from
=converted_from
,
780 uniform_from_type
=uniform_from_type
,
781 uniform_to_type
=uniform_to_type
,
782 conversions
=conversions
))
784 def _gen_to_target(self
):
785 if self
._ver
== '410':
786 conversion_values
= FLOAT_POS_ZERO
787 elif self
._ver
== '420':
788 conversion_values
= FLOAT_NEG_ZERO
791 for value
in conversion_values
:
792 to_value
= TestTuple
.float_hex_to_inv_double_hex(value
)
793 item
= {'from': value
, 'to': to_value
}
794 conversions
.append(item
)
796 self
.__gen
_zero
_sign
_exec
_test
(self
._conversion
_type
, self
._target
_full
_type
,
797 self
._uniform
_type
, self
._target
_full
_type
,
798 'implicit', 'from', conversions
)
800 def _gen_from_target(self
):
801 if self
._ver
== '410':
802 conversion_values
= DOUBLE_POS_ZERO
803 elif self
._ver
== '420':
804 conversion_values
= DOUBLE_NEG_ZERO
807 for value
in conversion_values
:
808 to_value
= TestTuple
.double_hex_to_inv_float_hex(value
)
809 item
= {'from': value
, 'to': to_value
}
810 conversions
.append(item
)
812 self
.__gen
_zero
_sign
_exec
_test
(self
._target
_full
_type
, self
._conversion
_type
,
813 self
._target
_full
_type
, self
._uniform
_type
,
814 'explicit', self
._conversion
_type
+ '(from)', conversions
)
820 parser
= argparse
.ArgumentParser(
821 description
="Generate shader tests that check the conversions from and "
828 help="Don't output files, just generate a list of filenames to stdout")
829 args
= parser
.parse_args()
831 np
.seterr(divide
='ignore')
833 for test
in (list(RegularTestTuple
.all_tests(args
.names_only
)) +
834 list(ZeroSignTestTuple
.all_tests(args
.names_only
))):
835 test
.generate_test_files()
836 for filename
in test
.filenames
:
840 if __name__
== '__main__':