summary/html: escape html
[piglit.git] / generated_tests / gen_conversion.py
blob810e0ef822a25e8ceec65db6bc663c4910fc2d69
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 from __future__ import print_function, division, absolute_import
27 import abc
28 import argparse
29 import itertools
30 import os
31 import struct
33 import numpy as np
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
57 # Double +/-inf
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
104 '0x7f800000'] # +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
112 '0xc0a00000', # -5.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
121 '0x40a00000', # +5.0
122 '0x4b800000', # +16777216.0
123 '0x7f7fffff'] # Positive maximum normalized
125 FLOAT_INT64_VALUES = ['0xcf800000', # -4294967296.0
126 '0xcb800000', # -16777216.0
127 '0xc0a00000', # -5.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
136 '0x40a00000', # +5.0
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
144 '0x40a00000', # +5.0
145 '0x4b800000', # +16777216.0
146 '0x4f800000'] # +4294967296.0
148 UINT64_VALUES = ['0', # Minimum
149 '5',
150 '2147483647', # Signed int32 low frontier
151 '2147483648', # Signed int32 up frontier
152 '4294967295', # Maximum unsigned int32
153 '4294967296',
154 '9223372036854775807', # Signed int64 low frontier
155 '9223372036854775808', # Signed int64 up frontier
156 '18446744073709551615'] # Maximum
158 INT64_VALUES = ['-9223372036854775808', # Minimum
159 '-2147483649',
160 '-2147483648',
161 '-5',
162 '-1',
163 '0',
164 '1',
165 '5',
166 '2147483647', # Signed int32 low frontier
167 '2147483648', # Signed int32 up frontier
168 '4294967295', # Maximum unsigned int32
169 '4294967296',
170 '9223372036854775807'] # Maximum
172 UINT_VALUES = ['0', # Minimum
173 '5',
174 '2147483647', # Signed int low frontier
175 '2147483648', # Signed int up frontier
176 '4294967295'] # Maximum
178 INT_VALUES = ['-2147483648', # Minimum
179 '-5',
180 '-1',
181 '0',
182 '1',
183 '5',
184 '2147483647'] # Maximum
186 BOOL_VALUES = ['0', # False
187 '1'] # True
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
192 test type.
195 assert isinstance(ver, str)
196 assert isinstance(test_type, str)
197 if ver.startswith('GL_'):
198 feature_dir = ver[3:].lower()
199 else:
200 feature_dir = 'glsl-{}.{}'.format(ver[0], ver[1:])
202 return os.path.join('spec', feature_dir, test_type,
203 'conversion')
206 class TestTuple(object):
207 """A float64 derived and other type derived tuple to generate the
208 needed conversion tests.
211 @staticmethod
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])
217 @staticmethod
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")
223 @staticmethod
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]
229 @staticmethod
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]
236 @staticmethod
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)
245 @staticmethod
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)
255 @staticmethod
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)
266 return str(int(x))
268 @staticmethod
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)
279 return str(int(x))
281 @staticmethod
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))))
287 @staticmethod
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)))
293 @staticmethod
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))
299 @staticmethod
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))
305 @staticmethod
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)
309 if x >= 2**31:
310 x -= 2**32
311 return str(x)
313 @staticmethod
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)
317 return str(x)
319 @staticmethod
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)
323 if x >= 2**63:
324 x -= 2**64
325 return str(x)
327 @staticmethod
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)
331 return str(x)
333 @staticmethod
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
344 @staticmethod
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'
351 @staticmethod
352 def double_hex_to_int_str(hstr):
353 """Returns an int32 string from a float64 hexadecimal
354 representation.
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))
364 @staticmethod
365 def double_hex_to_uint_str(hstr):
366 """Returns an uint32 string from a float64 hexadecimal
367 representation.
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))
377 @staticmethod
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)
386 @staticmethod
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)
396 @staticmethod
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)
407 return str(int(x))
409 @staticmethod
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)
420 return str(int(x))
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)
430 self._ver = ver
431 self._stage = stage
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)
439 self._filenames = []
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
454 else:
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'
481 else:
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
485 else:
486 self._uniform_type = self._conversion_type
487 self._target_full_type = target_type + dimensional_type
489 @abc.abstractmethod
490 def _gen_to_target(self):
491 """Generates the test files for conversions to float64."""
493 @abc.abstractmethod
494 def _gen_from_target(self):
495 """Generates the test files for conversions from float64."""
497 @property
498 def filenames(self):
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."""
509 self._filenames = []
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.
520 @staticmethod
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']
531 if not names_only:
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(
537 glsl_ver,
538 stages,
539 dimensions,
540 dimensions,
541 basic_types,
542 target_types):
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,
568 self._stage))
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(
576 ver=self._ver,
577 extensions=self._extensions,
578 from_type=from_type,
579 to_type=to_type,
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,
588 from_type, to_type))
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(
596 ver=self._ver,
597 extensions=self._extensions,
598 amount=self._amount,
599 from_type=from_type,
600 to_type=to_type,
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
639 else:
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,
648 converted_from)
649 converted_from = self._target_full_type + '(from)'
651 conversions = []
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,
702 converted_from)
704 converted_from = self._conversion_type + '(from)'
705 explicit = 'explicit'
706 else:
707 assert self._target_type in ('i64', 'u64')
709 conversions = []
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
722 +/-0.0 values.
725 @staticmethod
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']
732 basic_types = ['f']
733 glsl_ver = ['410', '420']
735 if not names_only:
736 for ver in glsl_ver:
737 utils.safe_makedirs(get_dir_name(ver, 'execution'))
739 for ver, stage, first_dimension, second_dimension, basic_type in itertools.product(
740 glsl_ver,
741 stages,
742 dimensions,
743 dimensions,
744 basic_types):
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,
766 from_type, to_type))
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(
775 ver=self._ver,
776 extensions=self._extensions,
777 amount=self._amount,
778 from_type=from_type,
779 to_type=to_type,
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
791 conversions = []
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
807 conversions = []
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)
818 def main():
819 """Main function."""
821 parser = argparse.ArgumentParser(
822 description="Generate shader tests that check the conversions from and "
823 "to fp64")
824 parser.add_argument(
825 '--names-only',
826 dest='names_only',
827 action='store_true',
828 default=False,
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:
838 print(filename)
841 if __name__ == '__main__':
842 main()