1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
|
# coding=utf-8
# Copyright (c) 2015-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 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 tests for variable index writes.
This creates a TestParams object for each invocation (using a factory to reduce
the number of duplicate objects), and then passes that into a mako template.
The template then formats that information into a shader_test for either the
fragment shader stage or the vertex shader stage.
"""
from __future__ import (
print_function, absolute_import, division, unicode_literals
)
import copy
import itertools
import os
from six.moves import range # pylint: disable=redefined-builtin
from modules import utils, glsl
from templates import template_dir
_TEMPLATES = template_dir(os.path.basename(os.path.splitext(__file__)[0]))
_VS_TEMPLATE = _TEMPLATES.get_template('vs.shader_test.mako')
_FS_TEMPLATE = _TEMPLATES.get_template('fs.shader_test.mako')
_DIRNAME = os.path.join('spec', 'glsl-{}', 'execution', 'variable-indexing')
class TestParams(object):
"""Object representing all of the parameters of a single test instance.
Provides all of the values using lazy properties, which tie in with the
ParamsFactory to store all of the values, speeding up run times.
"""
def __init__(self, mode, array_dim, matrix_dim, index_value, col,
value_type, glsl_version):
# pylint: disable=too-many-arguments
assert array_dim in [0, 3]
assert matrix_dim in [2, 3, 4]
self.mode = mode
self.array_dim = array_dim
self.matrix_dim = matrix_dim
self.index_value = index_value
self.col = '[{}]'.format(col)
self.value_type = value_type
self.version = glsl.Version(glsl_version)
@utils.lazy_property
def varying_comps(self):
if self.array_dim != 0:
return self.matrix_dim**2 * self.array_dim
else:
return self.matrix_dim**2
@utils.lazy_property
def base_type(self):
if int(self.version) >= 120:
return 'mat{0}x{0}'.format(self.matrix_dim)
else:
return 'mat{}'.format(self.matrix_dim)
@utils.lazy_property
def type(self):
if self.array_dim != 0 and int(self.version) >= 120:
return '{}[{}]'.format(self.base_type, self.array_dim)
else:
return self.base_type
@utils.lazy_property
def dim(self):
if self.array_dim != 0 and int(self.version) < 120:
return '[{}]'.format(self.array_dim)
else:
return ''
@utils.lazy_property
def row(self):
if self.value_type == 'float':
return '[row]'
else:
return ''
@utils.lazy_property
def idx(self):
if self.array_dim != 0:
return '[{}]'.format(self.index_value)
else:
return ''
@utils.lazy_property
def test_vec(self):
if self.matrix_dim == 2:
return ["0.803161418975390", "0.852987140792140"]
elif self.matrix_dim == 3:
return ["0.681652305322399", "0.210426138878113",
"0.185916924650237"]
elif self.matrix_dim == 4:
return ["0.0394868046587045", "0.8922408276905568",
"0.3337495624366961", "0.8732295730825839"]
@utils.lazy_property
def test_exp(self):
if self.matrix_dim == 2:
return ["0.708718134966688", "1.452243795483797"]
elif self.matrix_dim == 3:
return ["0.610649606928364", "0.711906885823636",
"0.312244778977868"]
elif self.matrix_dim == 4:
return ["1.03935908892461", "1.18846180713529", "1.10078681232072",
"1.72434439561820"]
@utils.lazy_property
def test_mat(self):
if self.matrix_dim == 2:
return [["0.241498998195656", "0.861223395812970"],
["0.603473877011433", "0.891622340451180"]]
elif self.matrix_dim == 3:
return [
["0.493944462129466", "0.722190133917966", "0.239853948232558"],
["0.550143078409278", "0.591962645398579", "0.467616286531193"],
["0.850846377186973", "0.511303112962423", "0.270815003356504"]
]
elif self.matrix_dim == 4:
return [["0.922040144261674", "0.158053783109488",
"0.357016429866574", "0.836368810383957"],
["0.560251913703792", "0.171634921595771",
"0.602494709909111", "0.693273570571311"],
["0.350720358904176", "0.912192627475775",
"0.688544081259531", "0.913891056231967"],
["0.442058176039301", "0.829835836794679",
"0.365674411003021", "0.879197364462782"]]
@utils.lazy_property
def test_sizes(self):
if self.array_dim == 0:
return [1]
elif self.index_value == 'index':
return list(range(1, self.array_dim + 1))
else:
return [2]
@utils.lazy_property
def test_columns(self):
if self.col == '[col]':
return list(range(1, self.matrix_dim + 1))
return [2]
@utils.lazy_property
def test_rows(self):
if self.value_type == 'float':
return list(range(1, self.matrix_dim + 1))
return [1]
@utils.lazy_property
def test_type(self):
# shader_runner always uses matDxD format
return 'mat{0}x{0}'.format(self.matrix_dim)
def test_matrix(self, column, row):
"""Generate the matrix used in a test section.
This will take the matrix used by the test, and replace specific values
with sentinal values, and return the matrix as a string.
"""
bad = ['666.0', '777.0', '888.0', '999.0']
mat = copy.deepcopy(self.test_mat)
if self.value_type == 'float':
mat[column][row] = bad[0]
else:
mat[column] = bad[0:self.matrix_dim]
ret = ''
for c in mat:
ret += ' '.join(c)
ret += ' '
return ret
@utils.lazy_property
def formated_version(self):
# Note: GLSLVersion.float() does division by 100
return '{:.2f}'.format(float(self.version))
class ParamsFactory(object): # pylint: disable=too-few-public-methods
"""A factory class that provides TestParam objects.
This cuts the number of new objects created by roughly 3/5.
"""
def __init__(self):
self.__stored = {}
def get(self, *args):
args = tuple(args)
try:
return self.__stored[args]
except KeyError:
params = TestParams(*args)
self.__stored[args] = params
return params
def make_vs(name, params):
"""Create a vertex shader test."""
dirname = _DIRNAME.format(params.formated_version)
utils.safe_makedirs(dirname)
with open(os.path.join(dirname, name), 'w') as f:
f.write(_VS_TEMPLATE.render_unicode(params=params))
print(name)
def make_fs(name, params):
"""Create a fragment shader test."""
dirname = _DIRNAME.format(params.formated_version)
utils.safe_makedirs(dirname)
with open(os.path.join(dirname, name), 'w') as f:
f.write(_FS_TEMPLATE.render_unicode(params=params))
print(name)
def main():
"""The main function."""
# Various choices that can be put together to produce a single test.
iter_ = itertools.product(
['110', '120'], # GLSL versions
[0, 3], # Array dimensions
[2, 3, 4], # Matrix dimensions
['varying', 'temp'], # modes
['col', 1], # columns
['fs', 'vs'], # shader stages
)
factory = ParamsFactory()
# This can be filled in to produce the file name for the test.
# Note that idx, col, row, and arr will need to have a '-' added to the end
# of the value if it is not empty
name = '{stage}-{mode}-{arr}mat{matrix_dim}-{idx}{col}{row}wr.shader_test'
for v, a, d, m, c, s in iter_:
for t in ['float', 'vec{}'.format(d)]:
if s == 'vs':
func = make_vs
elif s == 'fs':
if m == 'varying':
# Fragment shaders cannot write varyings
continue
func = make_fs
if a != 0:
arr = 'array-'
func(
name.format(stage=s,
mode=m,
matrix_dim=d,
arr=arr,
idx='',
col='col-' if c == 'col' else '',
row='row-' if t == 'float' else ''),
factory.get(m, a, d, 1, c, t, v))
else:
arr = ''
func(
name.format(stage=s,
mode=m,
matrix_dim=d,
arr=arr,
idx='index-' if a != 0 else '',
col='col-' if c == 'col' else '',
row='row-' if t == 'float' else ''),
factory.get(m, a, d, 'index', c, t, v))
if __name__ == '__main__':
main()
|