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"""
28 from modules
import utils
29 from textwrap
import dedent
30 from templates
import template_dir
32 TEMPLATES
= template_dir(os
.path
.basename(os
.path
.splitext(__file__
)[0]))
34 def get_array_index(size
):
35 return "[" + str(size
) + "]" if size
> 1 else ""
37 class BasicType(object):
38 def __init__(self
, type_name
, subtype
=None, size
=0, array_size
=1, qualifiers
=''):
40 self
.subtype
= subtype
41 self
._qualifiers
= qualifiers
42 self
.array_size
= array_size
46 return "{}{}".format(self
.name
, get_array_index(self
.array_size
))
51 while base_type
is not None:
52 all
.add(base_type
._qualifiers
)
53 base_type
= base_type
.subtype
54 result
= " ".join(all
).strip()
55 return result
+ " " if len(result
) else ""
60 while base_type
.has_subtype():
61 base_type
= base_type
.subtype
65 def has_subtype(self
):
66 return self
.subtype
is not None
69 return self
.array_size
> 1
72 def apply_indent(text
, prefix
):
74 for line
in text
.split('\n'):
76 result
+= "{}{}\n".format(prefix
, line
)
77 return result
.strip("\n")
80 def save_shader_text(filepath
, shader_text
):
81 with
open(filepath
, 'w') as test_file
:
82 test_file
.write(shader_text
)
85 def get_tests_path(folder
):
86 return os
.path
.join("spec", "arb_enhanced_layouts", folder
)
89 def get_index_var_name(dim
):
90 return chr(ord('a') + dim
)
93 def get_layout(location_idx
):
94 return "layout(location = {}) ".format(location_idx
) if location_idx
else ""
97 def generate_assignment(base_type
, dst
, src
):
100 dimension_num
= base_type
.depth()
101 while base_type
.has_subtype():
102 if base_type
.is_array():
104 deref
+= "[{}]".format(get_index_var_name(dimension_num
- dimension
))
105 base_type
= base_type
.subtype
107 # `convert` is a predefined function in mako file
108 return "{dst} += convert({src}{deref});".format(dst
=dst
, src
=src
,
111 def generate_conversion_func(base_type
):
113 for (int {idx} = {start}; {idx} < {len}; {idx}++) {{
117 root_type
= base_type
119 dimension_num
= base_type
.depth()
120 loop_code
= generate_assignment(base_type
, "color", "indata")
121 while base_type
.has_subtype():
122 idxname
= get_index_var_name(dimension_num
- dimension
)
123 loop_code
= dedent(gen_text_mask
).format(idx
=idxname
,
126 inner_text
=apply_indent(loop_code
, " " * 4))
127 base_type
= base_type
.subtype
130 if root_type
.is_array():
131 loop_code
= dedent(gen_text_mask
).format(idx
='a',
133 len=root_type
.array_size
,
134 inner_text
=apply_indent(loop_code
, " " * 4))
136 calc_color
= dedent("""\
137 vec4 calc_color(in {} indata{}) {{
138 vec4 color = vec4(0.0);
142 """).format(root_type
.name
, get_array_index(root_type
.array_size
), apply_indent(loop_code
, " " * 4))
146 def create_args_parser():
147 parser
= argparse
.ArgumentParser(
148 description
="Generate interface block linker tests")
155 help="Generate script running the tests (for development)")
158 '--oob-verbose-mode',
159 dest
='oob_verbose_mode',
162 help="Generate a lot of tests checking the out-of-bounds cases (for development)")
166 class TestEnv(object):
167 def __init__(self
, extensions
= []):
168 self
.extensions
= extensions
170 def generate_matching_test(self
, test_types
, filename
, block_location
):
171 declare_var_template
= "{qualifiers}{base_type} {prefix}{var_number}{array_size};\n"
173 extensions
= ["GL_ARB_enhanced_layouts",
174 "GL_ARB_separate_shader_objects",
175 "GL_ARB_arrays_of_arrays"] + self
.extensions
178 declare_uniform_types
= ""
179 declare_vs_output_types
= ""
180 assign_vs_output_types
= ""
181 calc_output_color
= ""
185 for base_type
in test_types
:
186 declare_uniform_types
+= declare_var_template
.format(qualifiers
= "uniform ",
187 base_type
= base_type
.name
,
188 prefix
="vs_uniform_",
189 var_number
= var_number
,
190 array_size
= get_array_index(base_type
.array_size
))
191 declare_vs_output_types
+= declare_var_template
.format(qualifiers
= base_type
.qualifiers(),
192 base_type
= base_type
.name
,
194 var_number
= var_number
,
195 array_size
= get_array_index(base_type
.array_size
))
196 assign_vs_output_types
+= ("vs_output.var_{var_number} = vs_uniform_{var_number};\n").format(var_number
= var_number
)
197 calc_output_color
+= ("fs_output += calc_color(vs_output.var_{var_number});\n").format(var_number
= var_number
)
198 if str(base_type
) not in unique_types
:
199 unique_types
.append(str(base_type
))
200 calc_color_func
+= generate_conversion_func(base_type
)
203 templ
= TEMPLATES
.get_template('basic.shader_test.mako')
204 shadertext
= templ
.render_unicode(declare_uniform_types
=declare_uniform_types
,
205 declare_vs_output_types
=apply_indent(declare_vs_output_types
, " " * 4),
206 assign_vs_output_types
=apply_indent(assign_vs_output_types
, " " * 4),
207 calc_output_color
=apply_indent(calc_output_color
, " " * 4),
208 calc_color
=calc_color_func
,
209 extensions
=extensions
,
210 layout
=get_layout(block_location
))
211 save_shader_text(filename
, shadertext
)
214 def test_matching(self
, test_types
, filename
):
215 for block_location
in [None, 1]:
216 location_name
= "_loc_{}".format(block_location
) if block_location
else ""
217 fullname
=get_tests_path("") + filename
+ location_name
+ ".shader_test"
218 self
.generate_matching_test(test_types
, fullname
, block_location
)
225 parser
= create_args_parser()
226 args
= parser
.parse_args()
230 print("SHADER_RUNNER=bin/shader_runner")
232 utils
.safe_makedirs(get_tests_path(""))
234 flat_qualifier
="flat"
237 BasicType("vec2", BasicType("float"), 2),
238 BasicType("vec3", BasicType("float"), 3),
239 BasicType("vec4", BasicType("float"), 4),
241 BasicType("int" , qualifiers
=flat_qualifier
),
242 BasicType("ivec2", BasicType("int"), 2, qualifiers
=flat_qualifier
),
243 BasicType("ivec3", BasicType("int"), 3, qualifiers
=flat_qualifier
),
244 BasicType("ivec4", BasicType("int"), 4, qualifiers
=flat_qualifier
),
246 BasicType("uint" , qualifiers
=flat_qualifier
),
247 BasicType("uvec2", BasicType("uint"), 2, qualifiers
=flat_qualifier
),
248 BasicType("uvec3", BasicType("uint"), 3, qualifiers
=flat_qualifier
),
249 BasicType("uvec4", BasicType("uint"), 4, qualifiers
=flat_qualifier
),
251 BasicType("mat2" , BasicType("vec2", BasicType("float"), 2), 2),
252 BasicType("mat3x2", BasicType("vec2", BasicType("float"), 2), 3),
253 BasicType("mat4x2", BasicType("vec2", BasicType("float"), 2), 4),
255 BasicType("mat2x3", BasicType("vec3", BasicType("float"), 3), 2),
256 BasicType("mat3" , BasicType("vec3", BasicType("float"), 3), 3),
257 BasicType("mat4x3", BasicType("vec3", BasicType("float"), 3), 4),
259 BasicType("mat2x4", BasicType("vec4", BasicType("float"), 4), 2),
260 BasicType("mat3x4", BasicType("vec4", BasicType("float"), 4), 3),
261 BasicType("mat4" , BasicType("vec4", BasicType("float"), 4), 4),
264 ALL_ATTR_TYPES_FP64
= [
265 BasicType("double", qualifiers
=flat_qualifier
),
266 BasicType("dvec2", BasicType("double"), 2, qualifiers
=flat_qualifier
),
267 BasicType("dvec3", BasicType("double"), 3, qualifiers
=flat_qualifier
),
268 BasicType("dvec4", BasicType("double"), 4, qualifiers
=flat_qualifier
),
270 BasicType("dmat2" , BasicType("dvec2", BasicType("double"), 2), 2, qualifiers
=flat_qualifier
),
271 BasicType("dmat3x2", BasicType("dvec2", BasicType("double"), 2), 3, qualifiers
=flat_qualifier
),
272 BasicType("dmat4x2", BasicType("dvec2", BasicType("double"), 2), 4, qualifiers
=flat_qualifier
),
274 BasicType("dmat2x3", BasicType("dvec3", BasicType("double"), 3), 2, qualifiers
=flat_qualifier
),
275 BasicType("dmat3" , BasicType("dvec3", BasicType("double"), 3), 3, qualifiers
=flat_qualifier
),
276 BasicType("dmat4x3", BasicType("dvec3", BasicType("double"), 3), 4, qualifiers
=flat_qualifier
),
278 BasicType("dmat2x4", BasicType("dvec4", BasicType("double"), 4), 2, qualifiers
=flat_qualifier
),
279 BasicType("dmat3x4", BasicType("dvec4", BasicType("double"), 4), 3, qualifiers
=flat_qualifier
),
280 BasicType("dmat4" , BasicType("dvec4", BasicType("double"), 4), 4, qualifiers
=flat_qualifier
),
283 ALL_ATTR_TYPES_64BIT
= [
284 BasicType("int64_t", qualifiers
=flat_qualifier
),
285 BasicType("i64vec2", BasicType("int64_t"), 2, qualifiers
=flat_qualifier
),
286 BasicType("i64vec3", BasicType("int64_t"), 3, qualifiers
=flat_qualifier
),
287 BasicType("i64vec4", BasicType("int64_t"), 4, qualifiers
=flat_qualifier
),
289 BasicType("uint64_t", qualifiers
=flat_qualifier
),
290 BasicType("u64vec2", BasicType("uint64_t"), 2, qualifiers
=flat_qualifier
),
291 BasicType("u64vec3", BasicType("uint64_t"), 3, qualifiers
=flat_qualifier
),
292 BasicType("u64vec4", BasicType("uint64_t"), 4, qualifiers
=flat_qualifier
),
296 for i
in range(0, 3, 1):
298 for j
in range(0 + i
, 21 + i
, 3):
299 ATTR_TYPES
.append(ALL_ATTR_TYPES
[j
])
300 TestEnv().test_matching(ATTR_TYPES
, ("matching_basic_types_{}").format(i
+ 1))
303 for i
in range(0, 2, 1):
305 for j
in range(0, 4, 1):
306 ATTR_TYPES
.append(ALL_ATTR_TYPES_64BIT
[i
+ 2 * j
])
307 TestEnv(["GL_ARB_gpu_shader_int64"]).test_matching(ATTR_TYPES
, ("matching_64bit_types_{}").format(i
+ 1))
309 for i
in range(0, 3, 1):
310 ATTR_TYPES
= [ALL_ATTR_TYPES_FP64
[0],
311 ALL_ATTR_TYPES_FP64
[1],
312 ALL_ATTR_TYPES_FP64
[2],
313 ALL_ATTR_TYPES_FP64
[3]]
315 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[4 + i
])
316 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[7 + i
])
317 ATTR_TYPES
.append(ALL_ATTR_TYPES_FP64
[10 + i
])
318 TestEnv(["GL_ARB_gpu_shader_fp64"]).test_matching(ATTR_TYPES
, ("matching_fp64_types_{}").format(i
+ 1))
321 #test https://gitlab.freedesktop.org/mesa/mesa/-/issues/3320
323 BasicType("vec2", BasicType("float"), 2),
324 BasicType("vec3", BasicType("float"), 3),
325 BasicType("float" , qualifiers
=flat_qualifier
),
326 BasicType("vec3", BasicType("float"), 3, array_size
=3),
327 BasicType("vec4", BasicType("float"), 4),
328 BasicType("vec3", BasicType("float"), 3),
329 BasicType("vec3", BasicType("float"), 3),
331 TestEnv().test_matching(ATTR_TYPES
, ("matching_basic_types_custom"))
333 #TestEnv(args, ATTR_TYPES, get_tests_path("execution/io-block-oob/basic-types"), [], True).test_oob()
334 #TestEnv(args, ATTR_TYPES_FP64, get_tests_path("execution/io-block-oob/fp64-types"), ["GL_ARB_gpu_shader_fp64"], True).test_oob()
335 #TestEnv(args, ATTR_TYPES_64BIT, get_tests_path("execution/io-block-oob/64bit-types"), ["GL_ARB_gpu_shader_int64"], True).test_oob()
338 if __name__
== '__main__':