framework/replay: re-try more aggressively, even over the 50x HTTP errors
[piglit.git] / generated_tests / gen_conversion.py
blob4f4348edb3abd852c3850e3422b99dc58442eb6f
1 # coding=utf-8
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
14 # Software.
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 import abc
27 import argparse
28 import itertools
29 import os
30 import struct
32 import numpy as np
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
56 # Double +/-inf
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
103 '0x7f800000'] # +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
111 '0xc0a00000', # -5.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
120 '0x40a00000', # +5.0
121 '0x4b800000', # +16777216.0
122 '0x7f7fffff'] # Positive maximum normalized
124 FLOAT_INT64_VALUES = ['0xcf800000', # -4294967296.0
125 '0xcb800000', # -16777216.0
126 '0xc0a00000', # -5.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
135 '0x40a00000', # +5.0
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
143 '0x40a00000', # +5.0
144 '0x4b800000', # +16777216.0
145 '0x4f800000'] # +4294967296.0
147 UINT64_VALUES = ['0', # Minimum
148 '5',
149 '2147483647', # Signed int32 low frontier
150 '2147483648', # Signed int32 up frontier
151 '4294967295', # Maximum unsigned int32
152 '4294967296',
153 '9223372036854775807', # Signed int64 low frontier
154 '9223372036854775808', # Signed int64 up frontier
155 '18446744073709551615'] # Maximum
157 INT64_VALUES = ['-9223372036854775808', # Minimum
158 '-2147483649',
159 '-2147483648',
160 '-5',
161 '-1',
162 '0',
163 '1',
164 '5',
165 '2147483647', # Signed int32 low frontier
166 '2147483648', # Signed int32 up frontier
167 '4294967295', # Maximum unsigned int32
168 '4294967296',
169 '9223372036854775807'] # Maximum
171 UINT_VALUES = ['0', # Minimum
172 '5',
173 '2147483647', # Signed int low frontier
174 '2147483648', # Signed int up frontier
175 '4294967295'] # Maximum
177 INT_VALUES = ['-2147483648', # Minimum
178 '-5',
179 '-1',
180 '0',
181 '1',
182 '5',
183 '2147483647'] # Maximum
185 BOOL_VALUES = ['0', # False
186 '1'] # True
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
191 test type.
194 assert isinstance(ver, str)
195 assert isinstance(test_type, str)
196 if ver.startswith('GL_'):
197 feature_dir = ver[3:].lower()
198 else:
199 feature_dir = 'glsl-{}.{}'.format(ver[0], ver[1:])
201 return os.path.join('spec', feature_dir, test_type,
202 'conversion')
205 class TestTuple(object):
206 """A float64 derived and other type derived tuple to generate the
207 needed conversion tests.
210 @staticmethod
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])
216 @staticmethod
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")
222 @staticmethod
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]
228 @staticmethod
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]
235 @staticmethod
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)
244 @staticmethod
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)
254 @staticmethod
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)
265 return str(int(x))
267 @staticmethod
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)
278 return str(int(x))
280 @staticmethod
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))))
286 @staticmethod
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)))
292 @staticmethod
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))
298 @staticmethod
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))
304 @staticmethod
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)
308 if x >= 2**31:
309 x -= 2**32
310 return str(x)
312 @staticmethod
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)
316 return str(x)
318 @staticmethod
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)
322 if x >= 2**63:
323 x -= 2**64
324 return str(x)
326 @staticmethod
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)
330 return str(x)
332 @staticmethod
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
343 @staticmethod
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'
350 @staticmethod
351 def double_hex_to_int_str(hstr):
352 """Returns an int32 string from a float64 hexadecimal
353 representation.
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))
363 @staticmethod
364 def double_hex_to_uint_str(hstr):
365 """Returns an uint32 string from a float64 hexadecimal
366 representation.
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))
376 @staticmethod
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)
385 @staticmethod
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)
395 @staticmethod
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)
406 return str(int(x))
408 @staticmethod
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)
419 return str(int(x))
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)
429 self._ver = ver
430 self._stage = stage
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)
438 self._filenames = []
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
453 else:
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'
480 else:
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
484 else:
485 self._uniform_type = self._conversion_type
486 self._target_full_type = target_type + dimensional_type
488 @abc.abstractmethod
489 def _gen_to_target(self):
490 """Generates the test files for conversions to float64."""
492 @abc.abstractmethod
493 def _gen_from_target(self):
494 """Generates the test files for conversions from float64."""
496 @property
497 def filenames(self):
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."""
508 self._filenames = []
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.
519 @staticmethod
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']
530 if not names_only:
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(
536 glsl_ver,
537 stages,
538 dimensions,
539 dimensions,
540 basic_types,
541 target_types):
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,
567 self._stage))
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(
575 ver=self._ver,
576 extensions=self._extensions,
577 from_type=from_type,
578 to_type=to_type,
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,
587 from_type, to_type))
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(
595 ver=self._ver,
596 extensions=self._extensions,
597 amount=self._amount,
598 from_type=from_type,
599 to_type=to_type,
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
638 else:
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,
647 converted_from)
648 converted_from = self._target_full_type + '(from)'
650 conversions = []
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,
701 converted_from)
703 converted_from = self._conversion_type + '(from)'
704 explicit = 'explicit'
705 else:
706 assert self._target_type in ('i64', 'u64')
708 conversions = []
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
721 +/-0.0 values.
724 @staticmethod
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']
731 basic_types = ['f']
732 glsl_ver = ['410', '420']
734 if not names_only:
735 for ver in glsl_ver:
736 utils.safe_makedirs(get_dir_name(ver, 'execution'))
738 for ver, stage, first_dimension, second_dimension, basic_type in itertools.product(
739 glsl_ver,
740 stages,
741 dimensions,
742 dimensions,
743 basic_types):
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,
765 from_type, to_type))
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(
774 ver=self._ver,
775 extensions=self._extensions,
776 amount=self._amount,
777 from_type=from_type,
778 to_type=to_type,
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
790 conversions = []
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
806 conversions = []
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)
817 def main():
818 """Main function."""
820 parser = argparse.ArgumentParser(
821 description="Generate shader tests that check the conversions from and "
822 "to fp64")
823 parser.add_argument(
824 '--names-only',
825 dest='names_only',
826 action='store_true',
827 default=False,
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:
837 print(filename)
840 if __name__ == '__main__':
841 main()