# coding=utf-8 # # Copyright © 2016 Intel Corporation # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice (including the next # paragraph) shall be included in all copies or substantial portions of the # Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. """Generate fp64 and int64 types conversion tests.""" import abc import argparse import itertools import os import struct import numpy as np from templates import template_dir from modules import utils TEMPLATES = template_dir(os.path.basename(os.path.splitext(__file__)[0])) # pylint: disable=bad-whitespace,line-too-long,bad-continuation DOUBLE_INFS = ['0xfff0000000000000', # -inf '0x7ff0000000000000'] # +inf DOUBLE_NEG_ZERO = ['0x8000000000000000'] # Negative underflow (-0.0) DOUBLE_POS_ZERO = ['0x0000000000000000'] # Positive underflow (+0.0) # Double values causing an underflow to zero in any other type DOUBLE_DENORMAL_VALUES = ['0x800fffffffffffff', # Negative maximum denormalized -- Denormalized may be flushed to 0 '0x8000000000000001', # Negative minimum denormalized -- Denormalized may be flushed to 0 '0x0000000000000001', # Positive minimum denormalized -- Denormalized may be flushed to 0 '0x000fffffffffffff'] # Positive maximum denormalized -- Denormalized may be flushed to 0 DOUBLE_NORMAL_VALUES = ['0x8010000000000000', # Negative minimum normalized '0x0010000000000000'] # Positive minimum normalized # Double +/-inf DOUBLE_FLOAT_INFS = ['0xc7effffff0000000', # Negative overflow (-inf) '0x47effffff0000000'] # Positive overflow (+inf) DOUBLE_FLOAT_VALUES = ['0xc7efffffefffffff', # Negative maximum normalized '0xc170000000000000', # -16777216.0 '0xc014000000000000', # -5.0 '0xbfff25ce60000000', # -1.9467300176620483 '0xb80fffffe0000000', # Negative minimum normalized '0xb69fffffffffffff', # Negative underflow '0x369fffffffffffff', # Positive underflow '0x380fffffe0000000', # Positive minimum normalized '0x3fff25ce60000000', # +1.9467300176620483 '0x4014000000000000', # +5.0 '0x4170000000000000', # +16777216.0 '0x47efffffefffffff'] # Positive maximum normalized DOUBLE_UINT_VALUES = ['0xbfeccccccccccccd', # -0.9 #'0x8010000000000000', # Negative minimum normalized -- Already checked #'0x800fffffffffffff', # Negative maximum denormalized -- Already checked #'0x8000000000000001', # Negative minimum denormalized -- Already checked #'0x8000000000000000', # Negative minimum (-0) -- Already checked #'0x0000000000000000', # Positive minimum (+0) -- Already checked '0x3fff25ce60000000', # +1.9467300176620483 '0x4014000000000000', # +5.0 '0x4170000000000000', # +16777216.0 '0x41dfffffffc00000', # Signed int low frontier (+2147483647) '0x41e0000000000000', # Signed int up frontier (+2147483648) '0x41efffffffe00000'] # Maximum (+4294967295) DOUBLE_INT_VALUES = ['0xc1e0000000000000', # Minimum (-2147483648) '0xc170000000000000', # -16777216.0 '0xc014000000000000', # -5.0 '0xbfff25ce60000000', # -1.9467300176620483 #'0x8000000000000000', # Negative minimum (-0) -- Already checked #'0x0000000000000000', # Minimum (+0) -- Already checked '0x3fff25ce60000000', # +1.9467300176620483 '0x4014000000000000', # +5.0 '0x4170000000000000', # +16777216.0 '0x41dfffffffc00000'] # Maximum (+2147483647) DOUBLE_BOOL_VALUES = [#'0x8010000000000000', # Minimum negative True value -- Already checked #'0x0000000000000000', # False -- Already checked #'0x0010000000000000', # Minimum positive True value -- Already checked ] FLOAT_INFS = ['0xff800000', # -inf '0x7f800000'] # +inf FLOAT_NEG_ZERO = ['0x80000000'] # Negative underflow (-0.0) FLOAT_POS_ZERO = ['0x00000000'] # Positive underflow (+0.0) FLOAT_VALUES = ['0xff7fffff', # Negative maximum normalized '0xcb800000', # -16777216.0 '0xc0a00000', # -5.0 '0xbff92e73', # -1.9467300176620483 '0x80800000', # Negative minimum normalized #'0x807fffff', # Negative maximum denormalized -- Denormalized may be flushed to 0 #'0x80000001', # Negative minimum denormalized -- Denormalized may be flushed to 0 #'0x00000001', # Positive minimum denormalized -- Denormalized may be flushed to 0 #'0x007fffff', # Positive maximum denormalized -- Denormalized may be flushed to 0 '0x00800000', # Positive minimum normalized '0x3ff92e73', # +1.9467300176620483 '0x40a00000', # +5.0 '0x4b800000', # +16777216.0 '0x7f7fffff'] # Positive maximum normalized FLOAT_INT64_VALUES = ['0xcf800000', # -4294967296.0 '0xcb800000', # -16777216.0 '0xc0a00000', # -5.0 '0xbff92e73', # -1.9467300176620483 '0x80800000', # Negative minimum normalized '0x807fffff', # Negative maximum denormalized '0x80000001', # Negative minimum denormalized '0x00000001', # Positive minimum denormalized '0x007fffff', # Positive maximum denormalized '0x00800000', # Positive minimum normalized '0x3ff92e73', # +1.9467300176620483 '0x40a00000', # +5.0 '0x4b800000', # +16777216.0 '0x4f800000'] # +4294967296.0 FLOAT_UINT64_VALUES = ['0x00000001', # Positive minimum denormalized '0x007fffff', # Positive maximum denormalized '0x00800000', # Positive minimum normalized '0x3ff92e73', # +1.9467300176620483 '0x40a00000', # +5.0 '0x4b800000', # +16777216.0 '0x4f800000'] # +4294967296.0 UINT64_VALUES = ['0', # Minimum '5', '2147483647', # Signed int32 low frontier '2147483648', # Signed int32 up frontier '4294967295', # Maximum unsigned int32 '4294967296', '9223372036854775807', # Signed int64 low frontier '9223372036854775808', # Signed int64 up frontier '18446744073709551615'] # Maximum INT64_VALUES = ['-9223372036854775808', # Minimum '-2147483649', '-2147483648', '-5', '-1', '0', '1', '5', '2147483647', # Signed int32 low frontier '2147483648', # Signed int32 up frontier '4294967295', # Maximum unsigned int32 '4294967296', '9223372036854775807'] # Maximum UINT_VALUES = ['0', # Minimum '5', '2147483647', # Signed int low frontier '2147483648', # Signed int up frontier '4294967295'] # Maximum INT_VALUES = ['-2147483648', # Minimum '-5', '-1', '0', '1', '5', '2147483647'] # Maximum BOOL_VALUES = ['0', # False '1'] # True # pylint: enable=bad-whitespace,line-too-long,bad-continuation def get_dir_name(ver, test_type): """Returns the directory name to save tests given a GLSL version and a test type. """ assert isinstance(ver, str) assert isinstance(test_type, str) if ver.startswith('GL_'): feature_dir = ver[3:].lower() else: feature_dir = 'glsl-{}.{}'.format(ver[0], ver[1:]) return os.path.join('spec', feature_dir, test_type, 'conversion') class TestTuple(object): """A float64 derived and other type derived tuple to generate the needed conversion tests. """ @staticmethod def float_to_hex(fvalue): """Returns the hexadecimal representation from a float32 value.""" assert isinstance(fvalue, np.float32) return hex(struct.unpack(' np.iinfo(np.dtype('int64')).max: return str(np.iinfo(np.dtype('int64')).max) if x < np.iinfo(np.dtype('int64')).min: return str(np.iinfo(np.dtype('int64')).min) return str(int(x)) @staticmethod def float_hex_to_uint64_str(hstr): """Returns the uint64 string representation from a float32 hexadecimal representation. """ assert isinstance(hstr, str) x = TestTuple.hex_to_float(hstr) if x > np.iinfo(np.dtype('uint64')).max: return str(np.iinfo(np.dtype('uint64')).max) if x < np.iinfo(np.dtype('uint64')).min: return str(np.iinfo(np.dtype('uint64')).min) return str(int(x)) @staticmethod def int_str_to_bool_str(istr): """Returns a bool/integer string from an (arbitrary size) integet string.""" assert isinstance(istr, str) return str(int(bool(int(istr)))) @staticmethod def int_str_to_float_hex(istr): """Returns a float32 hexadecimal representation from an (arbitrary size) integer string.""" assert isinstance(istr, str) return TestTuple.float_to_hex(np.float32(int(istr))) @staticmethod def int_str_to_double_hex(istr): """Returns a float64 hexadecimal representation from an (arbitrary size) integer string.""" assert isinstance(istr, str) return TestTuple.double_to_hex(float(istr)) @staticmethod def int_str_to_double_str(istr): """Returns a float64 string from an (arbitrary size) integer string.""" assert isinstance(istr, str) return str(float(istr)) @staticmethod def int_str_to_int32_str(istr): """Returns an int32 string from an (arbitrary size) integer string.""" x = int(istr) & (2**32 - 1) if x >= 2**31: x -= 2**32 return str(x) @staticmethod def int_str_to_uint32_str(istr): """Returns an uint32 string from an (arbitrary size) integer string.""" x = int(istr) & (2**32 - 1) return str(x) @staticmethod def int_str_to_int64_str(istr): """Returns an int64 string from an (arbitrary size) integer string.""" x = int(istr) & (2**64 - 1) if x >= 2**63: x -= 2**64 return str(x) @staticmethod def int_str_to_uint64_str(istr): """Returns an uint64 string from an (arbitrary size) integer string.""" x = int(istr) & (2**64 - 1) return str(x) @staticmethod def int_str_to_type_str(target_type): """Returns a function for converting an int string to a string for the given type.""" assert target_type in ('d', 'i64', 'u64') if target_type == 'd': return TestTuple.int_str_to_double_str elif target_type == 'i64': return TestTuple.int_str_to_int64_str elif target_type == 'u64': return TestTuple.int_str_to_uint64_str @staticmethod def double_hex_to_bool_str(hstr): """Returns a bool string from a float64 hexadecimal representation.""" assert isinstance(hstr, str) bool_double = TestTuple.hex_to_double(hstr) return '1' if bool_double != 0.0 else '0' @staticmethod def double_hex_to_int_str(hstr): """Returns an int32 string from a float64 hexadecimal representation. """ assert isinstance(hstr, str) int_double = TestTuple.hex_to_double(hstr) if int_double > np.iinfo(np.dtype('int32')).max: return str(np.iinfo(np.dtype('int32')).max) if int_double < np.iinfo(np.dtype('int32')).min: return str(np.iinfo(np.dtype('int32')).min) return str(int(int_double)) @staticmethod def double_hex_to_uint_str(hstr): """Returns an uint32 string from a float64 hexadecimal representation. """ assert isinstance(hstr, str) uint_double = TestTuple.hex_to_double(hstr) if uint_double > np.iinfo(np.dtype('uint32')).max: return str(np.iinfo(np.dtype('uint32')).max) if uint_double < np.iinfo(np.dtype('uint32')).min: return str(np.iinfo(np.dtype('uint32')).min) return str(int(uint_double)) @staticmethod def double_hex_to_float_hex(hstr): """Returns the float32 hexadecimal representation from a float64 hexadecimal representation. """ assert isinstance(hstr, str) float_double = np.float32(TestTuple.hex_to_double(hstr)) return TestTuple.float_to_hex(float_double) @staticmethod def double_hex_to_inv_float_hex(hstr): """Returns the inverted float32 hexadecimal representation from a float64 hexadecimal representation. """ assert isinstance(hstr, str) temp = np.divide(1.0, TestTuple.hex_to_double(hstr)) float_double = np.float32(temp) return TestTuple.float_to_hex(float_double) @staticmethod def double_hex_to_int64_str(hstr): """Returns the int64 string representation from a float64 hexadecimal representation. """ assert isinstance(hstr, str) x = TestTuple.hex_to_double(hstr) if x > np.iinfo(np.dtype('int64')).max: return str(np.iinfo(np.dtype('int64')).max) if x < np.iinfo(np.dtype('int64')).min: return str(np.iinfo(np.dtype('int64')).min) return str(int(x)) @staticmethod def double_hex_to_uint64_str(hstr): """Returns the uint64 string representation from a float64 hexadecimal representation. """ assert isinstance(hstr, str) x = TestTuple.hex_to_double(hstr) if x > np.iinfo(np.dtype('uint64')).max: return str(np.iinfo(np.dtype('uint64')).max) if x < np.iinfo(np.dtype('uint64')).min: return str(np.iinfo(np.dtype('uint64')).min) return str(int(x)) def __init__(self, ver, stage, first_dimension, second_dimension, basic_type, target_type, names_only): assert stage in ('vert', 'geom', 'frag') assert first_dimension in ('1', '2', '3', '4') assert second_dimension in ('1', '2', '3', '4') assert isinstance(names_only, bool) self._ver = ver self._stage = stage self._basic_type = basic_type self._target_type = target_type self._names_only = names_only self._target_full_type = '' self._conversion_type = '' self._uniform_type = '' self._amount = int(first_dimension) * int(second_dimension) self._filenames = [] self._extensions = [] if ver.startswith('GL_'): if basic_type == 'd' or target_type == 'd': self._extensions.append('GL_ARB_gpu_shader_fp64') if basic_type in ('i64', 'u64') or target_type in ('i64', 'u64'): self._extensions.append('GL_ARB_gpu_shader_int64') if first_dimension != '1': dimensional_type = 'mat' + first_dimension if first_dimension != second_dimension: dimensional_type += 'x' + second_dimension elif second_dimension != '1': dimensional_type = 'vec' + second_dimension else: dimensional_type = '' if dimensional_type == '': if basic_type == 'b': self._conversion_type = 'bool' self._uniform_type = 'int' elif basic_type == 'i': self._conversion_type = 'int' elif basic_type == 'u': self._conversion_type = 'uint' elif basic_type == 'f': self._conversion_type = 'float' elif basic_type == 'd': self._conversion_type = 'double' elif basic_type == 'i64': self._conversion_type = 'int64_t' elif basic_type == 'u64': self._conversion_type = 'uint64_t' if self._uniform_type == '': self._uniform_type = self._conversion_type if target_type == 'd': self._target_full_type = 'double' elif target_type == 'i64': self._target_full_type = 'int64_t' elif target_type == 'u64': self._target_full_type = 'uint64_t' else: self._conversion_type = (basic_type if basic_type != 'f' else '') + dimensional_type if basic_type == 'b': self._uniform_type = 'i' + dimensional_type else: self._uniform_type = self._conversion_type self._target_full_type = target_type + dimensional_type @abc.abstractmethod def _gen_to_target(self): """Generates the test files for conversions to float64.""" @abc.abstractmethod def _gen_from_target(self): """Generates the test files for conversions from float64.""" @property def filenames(self): """Returns the test file names this tuple will generate.""" if self._filenames == []: tmp = self._names_only self._names_only = True self.generate_test_files() self._names_only = tmp return self._filenames def generate_test_files(self): """Generate the GLSL parser tests.""" self._filenames = [] self._gen_to_target() self._gen_from_target() class RegularTestTuple(TestTuple): """Derived class for conversion tests using regular values within the edges of the used types. """ @staticmethod def all_tests(names_only): """Returns all the possible contained conversion test instances.""" assert isinstance(names_only, bool) stages = ['vert', 'geom', 'frag'] dimensions = ['1', '2', '3', '4'] basic_types = ['b', 'u', 'i', 'f', 'd', 'i64', 'u64'] target_types = ['d', 'i64', 'u64'] glsl_ver = ['GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400'] if not names_only: test_types = ['compiler', 'execution'] for ver, test_type in itertools.product(glsl_ver, test_types): utils.safe_makedirs(get_dir_name(ver, test_type)) for ver, stage, first_dimension, second_dimension, basic_type, target_type in itertools.product( glsl_ver, stages, dimensions, dimensions, basic_types, target_types): has_int64 = basic_type in ('i64', 'u64') or target_type in ('i64', 'u64') if (not (first_dimension != '1' and (second_dimension == '1' or basic_type not in ('f', 'd') or target_type != 'd')) and (basic_type not in target_types or basic_type < target_type) and ((ver == 'GL_ARB_gpu_shader_int64') == has_int64)): yield RegularTestTuple(ver, stage, first_dimension, second_dimension, basic_type, target_type, names_only) def __init__(self, ver, stage, first_dimension, second_dimension, basic_type, target_type, names_only): assert ver in ('GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400') assert basic_type in ('b', 'u', 'i', 'f', 'd', 'i64', 'u64') assert target_type in ('d', 'i64', 'u64') assert not (first_dimension != '1' and (second_dimension == '1' or basic_type not in ('f', 'd') or target_type != 'd')) super(RegularTestTuple, self).__init__(ver, stage, first_dimension, second_dimension, basic_type, target_type, names_only) def _gen_comp_test(self, from_type, to_type, converted_from): filename = os.path.join( get_dir_name(self._ver, 'compiler'), '{}-conversion-implicit-{}-{}-bad.{}'.format(self._stage, from_type, to_type, self._stage)) self._filenames.append(filename) if not self._names_only: with open(filename, 'w') as test_file: test_file.write(TEMPLATES.get_template( 'compiler.{}.mako'.format(self._stage)).render_unicode( ver=self._ver, extensions=self._extensions, from_type=from_type, to_type=to_type, converted_from=converted_from)) def _gen_exec_test(self, from_type, to_type, uniform_from_type, uniform_to_type, explicit, converted_from, conversions): filename = os.path.join( get_dir_name(self._ver, 'execution'), '{}-conversion-{}-{}-{}.shader_test'.format(self._stage, explicit, from_type, to_type)) self._filenames.append(filename) if not self._names_only: with open(filename, 'w') as test_file: test_file.write(TEMPLATES.get_template( 'execution.{}.shader_test.mako'.format(self._stage)).render_unicode( ver=self._ver, extensions=self._extensions, amount=self._amount, from_type=from_type, to_type=to_type, converted_from=converted_from, uniform_from_type=uniform_from_type, uniform_to_type=uniform_to_type, conversions=conversions)) def _gen_to_target(self): converted_from = 'from' explicit = 'implicit' if self._basic_type == 'b': conversion_values = BOOL_VALUES conversion_function = TestTuple.int_str_to_type_str(self._target_type) elif self._basic_type == 'i': conversion_values = INT_VALUES conversion_function = TestTuple.int_str_to_type_str(self._target_type) elif self._basic_type == 'u': conversion_values = UINT_VALUES conversion_function = TestTuple.int_str_to_type_str(self._target_type) elif self._basic_type == 'f': if self._target_type == 'd': conversion_values = FLOAT_INFS + FLOAT_NEG_ZERO + FLOAT_POS_ZERO + FLOAT_VALUES conversion_function = TestTuple.float_hex_to_double_hex elif self._target_type == 'i64': conversion_values = FLOAT_POS_ZERO + FLOAT_INT64_VALUES conversion_function = TestTuple.float_hex_to_int64_str elif self._target_type == 'u64': conversion_values = FLOAT_POS_ZERO + FLOAT_UINT64_VALUES conversion_function = TestTuple.float_hex_to_uint64_str elif self._basic_type == 'd': if self._target_type == 'i64': conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_INT_VALUES conversion_function = TestTuple.double_hex_to_int64_str elif self._target_type == 'u64': conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_UINT_VALUES conversion_function = TestTuple.double_hex_to_uint64_str elif self._basic_type in ('i64', 'u64'): if self._basic_type == 'i64': conversion_values = INT64_VALUES else: conversion_values = UINT64_VALUES conversion_function = TestTuple.int_str_to_type_str(self._target_type) if (self._basic_type == 'b' or (self._basic_type in ('f', 'd') and self._target_type in ('i64', 'u64')) or (self._basic_type == 'u' and self._target_type == 'i64')): explicit = 'explicit' self._gen_comp_test(self._conversion_type, self._target_full_type, converted_from) converted_from = self._target_full_type + '(from)' conversions = [] for value in conversion_values: to_value = conversion_function(value) item = {'from': value, 'to': to_value} conversions.append(item) self._gen_exec_test(self._conversion_type, self._target_full_type, self._uniform_type, self._target_full_type, explicit, converted_from, conversions) def _gen_from_target(self): converted_from = 'from' explicit = 'implicit' if self._target_type == 'd': if self._basic_type == 'b': conversion_values = DOUBLE_INFS + DOUBLE_NORMAL_VALUES + DOUBLE_BOOL_VALUES conversion_function = TestTuple.double_hex_to_bool_str elif self._basic_type == 'i': conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_INT_VALUES conversion_function = TestTuple.double_hex_to_int_str elif self._basic_type == 'u': conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_UINT_VALUES conversion_function = TestTuple.double_hex_to_uint_str elif self._basic_type == 'f': conversion_values = DOUBLE_INFS + DOUBLE_FLOAT_INFS + DOUBLE_FLOAT_VALUES conversion_function = TestTuple.double_hex_to_float_hex conversion_values = DOUBLE_NEG_ZERO + DOUBLE_POS_ZERO + conversion_values elif self._target_type in ('i64', 'u64'): if self._target_type == 'i64': conversion_values = INT64_VALUES elif self._target_type == 'u64': conversion_values = UINT64_VALUES if self._basic_type == 'b': conversion_function = TestTuple.int_str_to_bool_str elif self._basic_type == 'i': conversion_function = TestTuple.int_str_to_int32_str elif self._basic_type == 'u': conversion_function = TestTuple.int_str_to_uint32_str elif self._basic_type == 'f': conversion_function = TestTuple.int_str_to_float_hex elif self._basic_type == 'd': conversion_function = TestTuple.int_str_to_double_hex elif self._basic_type == 'i64': conversion_function = TestTuple.int_str_to_int64_str elif self._basic_type == 'i': conversion_function = TestTuple.int_str_to_uint64_str if self._basic_type != 'd': self._gen_comp_test(self._target_full_type, self._conversion_type, converted_from) converted_from = self._conversion_type + '(from)' explicit = 'explicit' else: assert self._target_type in ('i64', 'u64') conversions = [] for value in conversion_values: to_value = conversion_function(value) item = {'from': value, 'to': to_value} conversions.append(item) self._gen_exec_test(self._target_full_type, self._conversion_type, self._target_full_type, self._uniform_type, explicit, converted_from, conversions) class ZeroSignTestTuple(TestTuple): """Derived class for conversion tests using the float32 and float64 +/-0.0 values. """ @staticmethod def all_tests(names_only): """Returns all the possible zero sign conversion test instances.""" assert isinstance(names_only, bool) stages = ['vert', 'geom', 'frag'] dimensions = ['1', '2', '3', '4'] basic_types = ['f'] glsl_ver = ['410', '420'] if not names_only: for ver in glsl_ver: utils.safe_makedirs(get_dir_name(ver, 'execution')) for ver, stage, first_dimension, second_dimension, basic_type in itertools.product( glsl_ver, stages, dimensions, dimensions, basic_types): if not (first_dimension != '1' and second_dimension == '1'): yield ZeroSignTestTuple(ver, stage, first_dimension, second_dimension, basic_type, names_only) def __init__(self, ver, stage, first_dimension, second_dimension, basic_type, names_only): assert ver in ('410', '420') assert basic_type == 'f' assert not (first_dimension != '1' and second_dimension == '1') super(ZeroSignTestTuple, self).__init__(ver, stage, first_dimension, second_dimension, basic_type, 'd', names_only) def __gen_zero_sign_exec_test(self, from_type, to_type, uniform_from_type, uniform_to_type, explicit, converted_from, conversions): filename = os.path.join( get_dir_name(self._ver, 'execution'), '{}-conversion-{}-{}-{}-zero-sign.shader_test'.format(self._stage, explicit, from_type, to_type)) self._filenames.append(filename) if not self._names_only: with open(filename, 'w') as test_file: test_file.write(TEMPLATES.get_template( 'execution-zero-sign.{}.shader_test.mako'.format( self._stage)).render_unicode( ver=self._ver, extensions=self._extensions, amount=self._amount, from_type=from_type, to_type=to_type, converted_from=converted_from, uniform_from_type=uniform_from_type, uniform_to_type=uniform_to_type, conversions=conversions)) def _gen_to_target(self): if self._ver == '410': conversion_values = FLOAT_POS_ZERO elif self._ver == '420': conversion_values = FLOAT_NEG_ZERO conversions = [] for value in conversion_values: to_value = TestTuple.float_hex_to_inv_double_hex(value) item = {'from': value, 'to': to_value} conversions.append(item) self.__gen_zero_sign_exec_test(self._conversion_type, self._target_full_type, self._uniform_type, self._target_full_type, 'implicit', 'from', conversions) def _gen_from_target(self): if self._ver == '410': conversion_values = DOUBLE_POS_ZERO elif self._ver == '420': conversion_values = DOUBLE_NEG_ZERO conversions = [] for value in conversion_values: to_value = TestTuple.double_hex_to_inv_float_hex(value) item = {'from': value, 'to': to_value} conversions.append(item) self.__gen_zero_sign_exec_test(self._target_full_type, self._conversion_type, self._target_full_type, self._uniform_type, 'explicit', self._conversion_type + '(from)', conversions) def main(): """Main function.""" parser = argparse.ArgumentParser( description="Generate shader tests that check the conversions from and " "to fp64") parser.add_argument( '--names-only', dest='names_only', action='store_true', default=False, help="Don't output files, just generate a list of filenames to stdout") args = parser.parse_args() np.seterr(divide='ignore') for test in (list(RegularTestTuple.all_tests(args.names_only)) + list(ZeroSignTestTuple.all_tests(args.names_only))): test.generate_test_files() for filename in test.filenames: print(filename) if __name__ == '__main__': main()