4 # Copyright (c) 2020, 2021 Intel Corporation
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the 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 THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 """Generate interface block linker tests"""
30 from mako
import exceptions
32 from modules
import utils
33 from textwrap
import dedent
34 from templates
import template_dir
36 TEMPLATES
= template_dir(os
.path
.basename(os
.path
.splitext(__file__
)[0]))
38 def get_array_index(size
):
39 return "[" + str(size
) + "]" if size
> 1 else ""
41 class BasicType(object):
42 def __init__(self
, type_name
, subtype
=None, size
=0, array_size
=1, qualifiers
=''):
44 self
.subtype
= subtype
45 self
._qualifiers
= qualifiers
46 self
.array_size
= array_size
50 return "{}{}".format(self
.name
, get_array_index(self
.array_size
))
55 while base_type
is not None:
56 all
.add(base_type
._qualifiers
)
57 base_type
= base_type
.subtype
58 result
= " ".join(all
).strip()
59 return result
+ " " if len(result
) else ""
64 while base_type
.has_subtype():
65 base_type
= base_type
.subtype
69 def has_subtype(self
):
70 return self
.subtype
is not None
73 return self
.array_size
> 1
76 def apply_indent(text
, prefix
):
78 for line
in text
.split('\n'):
80 result
+= "{}{}\n".format(prefix
, line
)
81 return result
.strip("\n")
84 def save_shader_text(filepath
, shader_text
):
85 with
open(filepath
, 'w') as test_file
:
86 test_file
.write(shader_text
)
89 def get_tests_path(folder
):
90 return os
.path
.join("spec", "arb_enhanced_layouts", folder
)
93 def get_index_var_name(dim
):
94 return chr(ord('a') + dim
)
97 def get_layout(location_idx
):
98 return "layout(location = {}) ".format(location_idx
) if location_idx
else ""
101 def generate_assignment(base_type
, dst
, src
):
104 dimension_num
= base_type
.depth()
105 while base_type
.has_subtype():
106 if base_type
.is_array():
108 deref
+= "[{}]".format(get_index_var_name(dimension_num
- dimension
))
109 base_type
= base_type
.subtype
111 # `convert` is a predefined function in mako file
112 return "{dst} += convert({src}{deref});".format(dst
=dst
, src
=src
,
115 def generate_conversion_func(base_type
):
117 for (int {idx} = {start}; {idx} < {len}; {idx}++) {{
121 root_type
= base_type
123 dimension_num
= base_type
.depth()
124 loop_code
= generate_assignment(base_type
, "color", "indata")
125 while base_type
.has_subtype():
126 idxname
= get_index_var_name(dimension_num
- dimension
)
127 loop_code
= dedent(gen_text_mask
).format(idx
=idxname
,
130 inner_text
=apply_indent(loop_code
, " " * 4))
131 base_type
= base_type
.subtype
134 if root_type
.is_array():
135 loop_code
= dedent(gen_text_mask
).format(idx
='a',
137 len=root_type
.array_size
,
138 inner_text
=apply_indent(loop_code
, " " * 4))
140 calc_color
= dedent("""\
141 vec4 calc_color(in {} indata{}) {{
142 vec4 color = vec4(0.0);
146 """).format(root_type
.name
, get_array_index(root_type
.array_size
), apply_indent(loop_code
, " " * 4))
150 def create_args_parser():
151 parser
= argparse
.ArgumentParser(
152 description
="Generate interface block linker tests")
159 help="Generate script running the tests (for development)")
162 '--oob-verbose-mode',
163 dest
='oob_verbose_mode',
166 help="Generate a lot of tests checking the out-of-bounds cases (for development)")
170 class TestEnv(object):
171 def __init__(self
, extensions
= []):
172 self
.extensions
= extensions
174 def generate_matching_test(self
, test_types
, filename
, block_location
):
175 declare_var_template
= "{qualifiers}{base_type} {prefix}{var_number}{array_size};\n"
177 extensions
= ["GL_ARB_enhanced_layouts",
178 "GL_ARB_separate_shader_objects",
179 "GL_ARB_arrays_of_arrays"] + self
.extensions
182 declare_uniform_types
= ""
183 declare_vs_output_types
= ""
184 assign_vs_output_types
= ""
185 calc_output_color
= ""
189 for base_type
in test_types
:
190 declare_uniform_types
+= declare_var_template
.format(qualifiers
= "uniform ",
191 base_type
= base_type
.name
,
192 prefix
="vs_uniform_",
193 var_number
= var_number
,
194 array_size
= get_array_index(base_type
.array_size
))
195 declare_vs_output_types
+= declare_var_template
.format(qualifiers
= base_type
.qualifiers(),
196 base_type
= base_type
.name
,
198 var_number
= var_number
,
199 array_size
= get_array_index(base_type
.array_size
))
200 assign_vs_output_types
+= ("vs_output.var_{var_number} = vs_uniform_{var_number};\n").format(var_number
= var_number
)
201 calc_output_color
+= ("fs_output += calc_color(vs_output.var_{var_number});\n").format(var_number
= var_number
)
202 if str(base_type
) not in unique_types
:
203 unique_types
.append(str(base_type
))
204 calc_color_func
+= generate_conversion_func(base_type
)
207 templ
= TEMPLATES
.get_template('basic.shader_test.mako')
209 shadertext
= templ
.render_unicode(declare_uniform_types
=declare_uniform_types
,
210 declare_vs_output_types
=apply_indent(declare_vs_output_types
, " " * 4),
211 assign_vs_output_types
=apply_indent(assign_vs_output_types
, " " * 4),
212 calc_output_color
=apply_indent(calc_output_color
, " " * 4),
213 calc_color
=calc_color_func
,
214 extensions
=extensions
,
215 layout
=get_layout(block_location
))
217 print(exceptions
.text_error_template().render(), file=sys
.stderr
)
219 save_shader_text(filename
, shadertext
)
222 def test_matching(self
, test_types
, filename
):
223 for block_location
in [None, 1]:
224 location_name
= "_loc_{}".format(block_location
) if block_location
else ""
225 fullname
=get_tests_path("") + filename
+ location_name
+ ".shader_test"
226 self
.generate_matching_test(test_types
, fullname
, block_location
)
233 parser
= create_args_parser()
234 args
= parser
.parse_args()
238 print("SHADER_RUNNER=bin/shader_runner")
240 utils
.safe_makedirs(get_tests_path(""))
242 flat_qualifier
="flat"
245 BasicType("vec2", BasicType("float"), 2),
246 BasicType("vec3", BasicType("float"), 3),
247 BasicType("vec4", BasicType("float"), 4),
249 BasicType("int" , qualifiers
=flat_qualifier
),
250 BasicType("ivec2", BasicType("int"), 2, qualifiers
=flat_qualifier
),
251 BasicType("ivec3", BasicType("int"), 3, qualifiers
=flat_qualifier
),
252 BasicType("ivec4", BasicType("int"), 4, qualifiers
=flat_qualifier
),
254 BasicType("uint" , qualifiers
=flat_qualifier
),
255 BasicType("uvec2", BasicType("uint"), 2, qualifiers
=flat_qualifier
),
256 BasicType("uvec3", BasicType("uint"), 3, qualifiers
=flat_qualifier
),
257 BasicType("uvec4", BasicType("uint"), 4, qualifiers
=flat_qualifier
),
259 BasicType("mat2" , BasicType("vec2", BasicType("float"), 2), 2),
260 BasicType("mat3x2", BasicType("vec2", BasicType("float"), 2), 3),
261 BasicType("mat4x2", BasicType("vec2", BasicType("float"), 2), 4),
263 BasicType("mat2x3", BasicType("vec3", BasicType("float"), 3), 2),
264 BasicType("mat3" , BasicType("vec3", BasicType("float"), 3), 3),
265 BasicType("mat4x3", BasicType("vec3", BasicType("float"), 3), 4),
267 BasicType("mat2x4", BasicType("vec4", BasicType("float"), 4), 2),
268 BasicType("mat3x4", BasicType("vec4", BasicType("float"), 4), 3),
269 BasicType("mat4" , BasicType("vec4", BasicType("float"), 4), 4),
272 ALL_ATTR_TYPES_FP64
= [
273 BasicType("double", qualifiers
=flat_qualifier
),
274 BasicType("dvec2", BasicType("double"), 2, qualifiers
=flat_qualifier
),
275 BasicType("dvec3", BasicType("double"), 3, qualifiers
=flat_qualifier
),
276 BasicType("dvec4", BasicType("double"), 4, qualifiers
=flat_qualifier
),
278 BasicType("dmat2" , BasicType("dvec2", BasicType("double"), 2), 2, qualifiers
=flat_qualifier
),
279 BasicType("dmat3x2", BasicType("dvec2", BasicType("double"), 2), 3, qualifiers
=flat_qualifier
),
280 BasicType("dmat4x2", BasicType("dvec2", BasicType("double"), 2), 4, qualifiers
=flat_qualifier
),
282 BasicType("dmat2x3", BasicType("dvec3", BasicType("double"), 3), 2, qualifiers
=flat_qualifier
),
283 BasicType("dmat3" , BasicType("dvec3", BasicType("double"), 3), 3, qualifiers
=flat_qualifier
),
284 BasicType("dmat4x3", BasicType("dvec3", BasicType("double"), 3), 4, qualifiers
=flat_qualifier
),
286 BasicType("dmat2x4", BasicType("dvec4", BasicType("double"), 4), 2, qualifiers
=flat_qualifier
),
287 BasicType("dmat3x4", BasicType("dvec4", BasicType("double"), 4), 3, qualifiers
=flat_qualifier
),
288 BasicType("dmat4" , BasicType("dvec4", BasicType("double"), 4), 4, qualifiers
=flat_qualifier
),
291 ALL_ATTR_TYPES_64BIT
= [
292 BasicType("int64_t", qualifiers
=flat_qualifier
),
293 BasicType("i64vec2", BasicType("int64_t"), 2, qualifiers
=flat_qualifier
),
294 BasicType("i64vec3", BasicType("int64_t"), 3, qualifiers
=flat_qualifier
),
295 BasicType("i64vec4", BasicType("int64_t"), 4, qualifiers
=flat_qualifier
),
297 BasicType("uint64_t", qualifiers
=flat_qualifier
),
298 BasicType("u64vec2", BasicType("uint64_t"), 2, qualifiers
=flat_qualifier
),
299 BasicType("u64vec3", BasicType("uint64_t"), 3, qualifiers
=flat_qualifier
),
300 BasicType("u64vec4", BasicType("uint64_t"), 4, qualifiers
=flat_qualifier
),
304 for i
in range(0, 3, 1):
306 for j
in range(0 + i
, 21 + i
, 3):
307 ATTR_TYPES
.append(ALL_ATTR_TYPES
[j
])
308 TestEnv().test_matching(ATTR_TYPES
, ("matching_basic_types_{}").format(i
+ 1))
311 for i
in range(0, 2, 1):
313 for j
in range(0, 4, 1):
314 ATTR_TYPES
.append(ALL_ATTR_TYPES_64BIT
[i
+ 2 * j
])
315 TestEnv(["GL_ARB_gpu_shader_int64"]).test_matching(ATTR_TYPES
, ("matching_64bit_types_{}").format(i
+ 1))
317 for i
in range(0, 3, 1):
318 ATTR_TYPES
= [ALL_ATTR_TYPES_FP64
[0],
319 ALL_ATTR_TYPES_FP64
[1],
320 ALL_ATTR_TYPES_FP64
[2],
321 ALL_ATTR_TYPES_FP64
[3]]
323 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[4 + i
])
324 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[7 + i
])
325 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[10 + i
])
326 TestEnv(["GL_ARB_gpu_shader_fp64"]).test_matching(ATTR_TYPES
, ("matching_fp64_types_{}").format(i
+ 1))
329 #test https://gitlab.freedesktop.org/mesa/mesa/-/issues/3320
331 BasicType("vec2", BasicType("float"), 2),
332 BasicType("vec3", BasicType("float"), 3),
333 BasicType("float" , qualifiers
=flat_qualifier
),
334 BasicType("vec3", BasicType("float"), 3, array_size
=3),
335 BasicType("vec4", BasicType("float"), 4),
336 BasicType("vec3", BasicType("float"), 3),
337 BasicType("vec3", BasicType("float"), 3),
339 TestEnv().test_matching(ATTR_TYPES
, ("matching_basic_types_custom"))
341 #TestEnv(args, ATTR_TYPES, get_tests_path("execution/io-block-oob/basic-types"), [], True).test_oob()
342 #TestEnv(args, ATTR_TYPES_FP64, get_tests_path("execution/io-block-oob/fp64-types"), ["GL_ARB_gpu_shader_fp64"], True).test_oob()
343 #TestEnv(args, ATTR_TYPES_64BIT, get_tests_path("execution/io-block-oob/64bit-types"), ["GL_ARB_gpu_shader_int64"], True).test_oob()
346 if __name__
== '__main__':