1# coding=utf-8 2# Copyright (c) 2015 Intel Corporation 3 4# Permission is hereby granted, free of charge, to any person obtaining a copy 5# of this software and associated documentation files (the "Software"), to deal 6# in the Software without restriction, including without limitation the rights 7# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8# copies of the Software, and to permit persons to whom the Software is 9# furnished to do so, subject to the following conditions: 10 11# The above copyright notice and this permission notice shall be included in 12# all copies or substantial portions of the Software. 13 14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20# SOFTWARE. 21 22"""Generate tests for glsl 1.10 and 1.20 variable index reads.""" 23 24import os 25import itertools 26 27from templates import template_dir 28from modules.utils import lazy_property, safe_makedirs 29 30TEMPLATES = template_dir(os.path.basename(os.path.splitext(__file__)[0])) 31FS_TEMPLATE = TEMPLATES.get_template('fs.shader_test.mako') 32VS_TEMPLATE = TEMPLATES.get_template('vs.shader_test.mako') 33DIRNAME = os.path.join('spec', 'glsl-{}', 'execution', 'variable-indexing') 34 35 36class TestParams(object): 37 """Parameters for a single test. 38 39 This is all of the non-formatting logic of the test. Each property is 40 wrapped with a lazy_property decorator, which means the data is cached 41 after it is calculated once. 42 43 """ 44 def __init__(self, matrix_dim, array_dim, mode, index_value, col, 45 expect_type, glsl_version): 46 self.matrix_dim = matrix_dim 47 self.array_dim = array_dim 48 self.mode = mode 49 self.index_value = index_value 50 self.__col = col 51 self.expect_type = expect_type 52 53 assert glsl_version in [110, 120] 54 self.glsl_version = glsl_version 55 56 @lazy_property 57 def idx(self): 58 if self.array_dim != 0: 59 return '[{}]'.format(self.index_value) 60 else: 61 return '' 62 63 @lazy_property 64 def cxr_type(self): 65 return 'mat{0}x{0}'.format(self.matrix_dim) 66 67 @lazy_property 68 def base_type(self): 69 if self.glsl_version == 120: 70 return self.cxr_type 71 else: 72 return 'mat{}'.format(self.matrix_dim) 73 74 @lazy_property 75 def type(self): 76 if self.array_dim != 0 and self.glsl_version == 120: 77 return '{}[{}]'.format(self.base_type, self.array_dim) 78 else: 79 return self.base_type 80 81 @lazy_property 82 def dim(self): 83 if self.array_dim != 0 and self.glsl_version == 110: 84 return '[{}]'.format(self.array_dim) 85 else: 86 # XXX: should this be an error? 87 return '' 88 89 @lazy_property 90 def row(self): 91 if self.expect_type == 'float': 92 return '[row]' 93 else: 94 # XXX: Should this be an error? 95 return '' 96 97 @lazy_property 98 def col(self): 99 return '[{}]'.format(self.__col) 100 101 @lazy_property 102 def test_sizes(self): 103 if self.array_dim == 0: 104 return [1] 105 elif self.index_value == 'index': 106 return list(range(1, 1 + self.array_dim)) 107 else: 108 return [2] 109 110 @lazy_property 111 def test_columns(self): 112 if self.col == '[col]': 113 return list(range(1, 1 + self.matrix_dim)) 114 else: 115 return [2] 116 117 @lazy_property 118 def test_rows(self): 119 if self.expect_type == 'float': 120 return list(range(1, 1 + self.matrix_dim)) 121 else: 122 return [1] 123 124 @lazy_property 125 def test_array_dim(self): 126 if (self.mode == 'uniform' and 127 self.glsl_version == 110 and 128 self.array_dim != 0 and 129 self.index_value != 'index'): 130 return self.index_value + 1 131 else: 132 return self.array_dim 133 134 @lazy_property 135 def varying_comps(self): 136 if self.array_dim != 0: 137 return 4 + self.matrix_dim**2 * self.array_dim 138 else: 139 return 4 + self.matrix_dim**2 140 141 @lazy_property 142 def formated_version(self): 143 return '{:.2f}'.format(float(self.glsl_version) / 100) 144 145 146def make_fs(name, params): 147 """Generate a fragment shader test.""" 148 dirname = DIRNAME.format(params.formated_version) 149 safe_makedirs(dirname) 150 with open(os.path.join(dirname, name), 'w') as f: 151 f.write(FS_TEMPLATE.render_unicode(params=params)) 152 print(name) 153 154 155def make_vs(name, params): 156 """Generate a vertex shader test.""" 157 dirname = DIRNAME.format(params.formated_version) 158 safe_makedirs(dirname) 159 with open(os.path.join(dirname, name), 'w') as f: 160 f.write(VS_TEMPLATE.render_unicode(params=params)) 161 print(name) 162 163 164def main(): 165 """Generate the tests.""" 166 modes = ['temp', 'uniform', 'varying'] 167 array_dims = [0, 3] 168 matrix_dims = [2, 3, 4] 169 glsl_versions = [110, 120] 170 cols = [1, 'col'] 171 stages = ['fs', 'vs'] 172 iter_ = itertools.product(stages, modes, array_dims, matrix_dims, 173 glsl_versions, cols) 174 for stage, mode, array_dim, matrix_dim, glsl_version, col in iter_: 175 if stage == 'vs': 176 func = make_vs 177 else: 178 func = make_fs 179 180 for expect in ['float', 'vec{}'.format(matrix_dim)]: 181 if array_dim != 0: 182 arr = 'array-' 183 idx_text = 'index-' 184 185 func( 186 '{stage}-{mode}-{arr}mat{matrix_dim}-{col}{row}rd.shader_test'.format( 187 stage=stage, 188 mode=mode, 189 arr=arr, 190 matrix_dim=matrix_dim, 191 col='col-' if col == 'col' else '', 192 row='row-' if expect == 'float' else ''), 193 TestParams(matrix_dim, array_dim, mode, 1, col, expect, 194 glsl_version)) 195 else: 196 arr = '' 197 idx_text = '' 198 199 func( 200 '{stage}-{mode}-{arr}mat{matrix_dim}-{idx_text}{col}{row}rd.shader_test'.format( 201 stage=stage, 202 mode=mode, 203 arr=arr, 204 matrix_dim=matrix_dim, 205 idx_text=idx_text, 206 col='col-' if col == 'col' else '', 207 row='row-' if expect == 'float' else ''), 208 TestParams(matrix_dim, array_dim, mode, 'index', col, expect, 209 glsl_version)) 210 211 212if __name__ == '__main__': 213 main() 214