4 # Copyright (c) 2019 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 in/out tests for 64 bit types. """
32 from textwrap
import dedent
33 from mako
.template
import Template
34 from mako
import exceptions
40 class VaryingType(object):
41 __slots__
= ['type', 'members', 'name']
43 def __init__(self
, type, members
=None):
45 self
.members
= members
49 VaryingInstance
= collections
.namedtuple(
50 'VaryingInstance', ['varying_type', 'setters', 'checkers', 'full_name'])
53 def scalar_assignment(type, name
, data
):
54 """Return a GLSL code string to assign a scalar to its expected value."""
57 return "{} = {};".format(name
,
58 'false' if int(data
) == 0 else 'true')
60 return "{} = {}u;".format(name
, data
)
62 return "{} = {};".format(name
, data
)
63 elif type == "uint64_t":
64 return "{} = {}ul;".format(name
, data
)
65 elif type == "int64_t":
66 return "{} = {}l;".format(name
, data
)
68 # Not all implementations support the bit-cast operators that are used
69 # to do bit-exact comparisons. For this reason float_match needs the
70 # float data and the bit-exact data.
72 bits
= random_ubo
.bit_exact_data(data
, "float")
73 return "{} = float_get({}, {}u);".format(name
, data
, bits
)
74 elif type == "double":
75 bits
= random_ubo
.bit_exact_data(data
, "double")
80 hi
= "0x" + bits
[2:10]
81 lo
= "0x" + bits
[10:18]
83 return "{} = double_get(uvec2({}, {}));".format(name
, lo
, hi
)
85 raise Exception("Unknown scalar type {}".format(type))
88 def vector_assignment(type, name
, data
):
89 """Return a list of GLSL code strings that assign each field of a vector
90 to its expected value.
92 scalar
= random_ubo
.vector_base_type(type)
93 components
= ["x", "y", "z", "w"]
95 return [scalar_assignment(scalar
,
96 "{}.{}".format(name
, "xyzw"[i
]),
98 for i
in range(random_ubo
.vector_size(type))]
101 def matrix_assignment(type, name
, data
):
102 """Return a list of GLSL code strings that assign each field of a matrix
105 c
, r
= random_ubo
.matrix_dimensions(type)
108 column_type
= "dvec{}".format(r
)
110 column_type
= "vec{}".format(r
)
115 data_pairs
.extend(vector_assignment(
117 "{}[{}]".format(name
, i
),
118 data
[(i
* r
):(i
* r
) + r
]))
123 def create_array(base_type
, size
):
124 return "{}[{}]".format(base_type
, size
)
127 def array_base_type(varying_type
):
128 t
= copy
.copy(varying_type
)
129 t
.type = random_ubo
.array_base_type(t
.type)
134 def create_getters_and_setters(varying_type
, full_name
, instances
):
136 full_name
= varying_type
.name
137 elif varying_type
.name
is not None:
138 full_name
+= '.' + varying_type
.name
140 if random_ubo
.isarray(varying_type
.type):
141 base_type
= array_base_type(varying_type
)
142 for i
in range(random_ubo
.array_elements(varying_type
.type)):
143 indexed_name
= full_name
+ '[' + str(i
) + ']'
144 create_getters_and_setters(base_type
, indexed_name
, instances
)
146 elif random_ubo
.isstructure(varying_type
.type):
147 for m
in varying_type
.members
:
148 create_getters_and_setters(m
, full_name
, instances
)
151 v
= VaryingInstance(varying_type
, [], [], full_name
)
153 raw_data
= random_ubo
.random_data(varying_type
.type, full_name
, 0)
154 data
= raw_data
.split(" ")
156 if random_ubo
.isscalar(varying_type
.type):
157 v
.checkers
.append(random_ubo
.scalar_derp(varying_type
.type,
161 scalar_assignment(varying_type
.type, full_name
, data
[0]))
162 elif random_ubo
.isvector(varying_type
.type):
163 v
.checkers
.extend(random_ubo
.vector_derp(varying_type
.type,
167 vector_assignment(varying_type
.type, full_name
, data
))
168 elif random_ubo
.ismatrix(varying_type
.type):
169 v
.checkers
.extend(random_ubo
.matrix_derp(varying_type
.type,
173 matrix_assignment(varying_type
.type, full_name
, data
))
178 def assign_names(varying_type
, names
):
179 if random_ubo
.isarray(varying_type
.type):
180 varying_type
.name
= names
.get_name(
181 random_ubo
.without_array(varying_type
.type))
183 varying_type
.name
= names
.get_name(varying_type
.type)
185 if varying_type
.members
:
186 for m
in varying_type
.members
:
187 assign_names(m
, names
)
190 def gather_structs(varying_type
, structs
):
191 if random_ubo
.isarray(varying_type
.type):
192 base_type
= array_base_type(varying_type
)
193 gather_structs(base_type
, structs
)
194 elif random_ubo
.isstructure(varying_type
.type):
195 for m
in varying_type
.members
:
196 gather_structs(m
, structs
)
198 structs
.append(varying_type
)
201 def stringify_array_dimensions(type):
204 while random_ubo
.isarray(base_type
):
205 s
+= "@{}".format(random_ubo
.array_elements(base_type
))
206 base_type
= random_ubo
.array_base_type(base_type
)
210 def stringify_varying_type(varying_type
):
211 if random_ubo
.isarray(varying_type
.type):
212 name
= "{}{}".format(random_ubo
.without_array(varying_type
.type),
213 stringify_array_dimensions(varying_type
.type))
215 name
= varying_type
.type
217 if varying_type
.members
:
218 for m
in varying_type
.members
:
219 name
+= "-" + stringify_varying_type(m
)
224 def generate_file_name(root_types
, explicit_locations
):
225 name
= "vs-out-fs-in-"
226 name
+= "-and-".join(
227 [stringify_varying_type(t
) for t
in root_types
])
228 if explicit_locations
:
229 name
+= "-location-0"
230 return name
+ ".shader_test"
233 def do_test(root_types
, explicit_locations
, glsl_version
, extensions
,
235 if explicit_locations
and len(root_types
) > 1:
238 basename
= generate_file_name(root_types
, explicit_locations
)
239 fullname
= os
.path
.join(tests_path
, basename
)
243 shader_file
= open(fullname
, "w", buffering
=1)
245 names
= random_ubo
.unique_name_dict()
250 for type in root_types
:
251 assign_names(type, names
)
252 create_getters_and_setters(type, None, instances
)
253 gather_structs(type, structs
)
255 t
= Template(dedent("""\
257 GLSL >= ${glsl_version // 100}.${glsl_version % 100}
258 % for ext in extensions:
262 % if explicit_locations:
263 GL_ARB_explicit_attrib_location
267 % for ext in extensions:
268 #extension ${ext}: require
270 #extension GL_ARB_shader_bit_encoding: enable
271 #extension GL_ARB_gpu_shader5: enable
273 % if explicit_locations:
274 #extension GL_ARB_explicit_attrib_location : require
277 precision highp float;
278 % for s in structures:
281 % for m in s.members:
282 ${"{:<15}".format(m.type)} ${m.name};
287 % for r in root_types:
288 % if explicit_locations:
291 flat out ${"{:<10}".format(r.type)} ${r.name};
294 in vec4 piglit_vertex;
296 #if defined(GL_ARB_shader_bit_encoding) || defined(GL_ARB_gpu_shader5) || __VERSION__ >= 430
297 float float_get(float f, uint bits) { return uintBitsToFloat(bits); }
299 float float_get(float f, uint bits) { return f; }
301 % if glsl_version >= 400 or "GL_ARB_gpu_shader_fp64" in extensions:
302 double double_get(uvec2 bits) { return packDouble2x32(bits); }
307 % for inst in instances:
308 % for s in inst.setters:
313 gl_Position = piglit_vertex;
317 % for ext in extensions:
318 #extension ${ext}: require
320 #extension GL_ARB_shader_bit_encoding: enable
321 #extension GL_ARB_gpu_shader5: enable
323 % if explicit_locations:
324 #extension GL_ARB_explicit_attrib_location : require
327 precision highp float;
329 % for s in structures:
331 % for m in s.members:
332 ${"{:<15}".format(m.type)} ${m.name};
337 % for r in root_types:
338 % if explicit_locations:
341 flat in ${"{:<11}".format(r.type)} ${r.name};
344 out vec4 piglit_fragcolor;
346 #if defined(GL_ARB_shader_bit_encoding) || defined(GL_ARB_gpu_shader5) || __VERSION__ >= 430
347 bool float_match(float u, float f, uint bits) { return floatBitsToUint(u) == bits; }
349 bool float_match(float u, float f, uint bits) { return u == f; }
351 % if glsl_version >= 400 or "GL_ARB_gpu_shader_fp64" in extensions:
352 bool double_match(double u, uvec2 bits) { return unpackDouble2x32(u) == bits; }
359 % for inst in instances:
360 % for s in inst.checkers:
366 piglit_fragcolor = pass ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
373 probe all rgba 0.0 1.0 0.0 1.0"""))
376 shader
= t
.render(glsl_version
=glsl_version
,
377 root_types
=root_types
,
378 explicit_locations
=explicit_locations
,
380 extensions
=extensions
,
383 print(exceptions
.text_error_template().render(), file=sys
.stderr
)
386 shader_file
.write(shader
)
390 def do_test_permutations(root_types
, glsl_version
, extensions
, tests_path
):
391 without_outer_struct
= []
392 for type in root_types
:
393 if random_ubo
.isstructure(type.type):
394 without_outer_struct
.extend(m
for m
in type.members
)
396 without_outer_struct
.append(type)
398 do_test(root_types
, False, glsl_version
, extensions
, tests_path
)
399 do_test(root_types
, True, glsl_version
,
400 extensions
+ ["GL_ARB_separate_shader_objects"], tests_path
)
401 do_test(without_outer_struct
, False, glsl_version
, extensions
, tests_path
)
404 fp64_ext_path
= os
.path
.join("spec", "arb_gpu_shader_fp64", "execution",
406 fp64_core_path
= os
.path
.join("spec", "glsl-4.00", "execution",
408 int64_path
= os
.path
.join("spec", "arb_gpu_shader_int64", "execution",
411 for path
in [fp64_ext_path
, fp64_core_path
, int64_path
]:
414 except OSError as exc
:
415 if exc
.errno
!= errno
.EEXIST
or not os
.path
.isdir(path
):
418 INT64_VEC_TYPES
= [None, "int64_t", "i64vec2", "i64vec3", "i64vec4"]
419 UINT64_VEC_TYPES
= [None, "uint64_t", "u64vec2", "u64vec3", "u64vec4"]
420 FLOAT_VEC_TYPES
= [None, "float", "vec2", "vec3", "vec4"]
421 DOUBLE_VEC_TYPES
= [None, "double", "dvec2", "dvec3", "dvec4"]
423 DOUBLE_MAT_TYPES
= ["dmat2x2", "dmat2x3", "dmat2x4", "dmat3x2", "dmat3x3",
424 "dmat3x4", "dmat4x2", "dmat4x3", "dmat4x4"]
429 def do_common_64bit_tests(glsl_version
, extensions
, name_arr
, tests_path
):
431 for i
in range(1, 4):
432 tests
.append([VT("S1", [VT(name_arr
[i
])])])
434 tests
.append([VT("S1", [VT(name_arr
[i
] + "[4]")])])
436 for j
in range(1, 4):
437 tests
.append([VT("S1", [VT(FLOAT_VEC_TYPES
[j
]), VT(name_arr
[i
])])])
439 tests
.append([VaryingType("S1",
440 [VT("float"), VT("float"), VT("float"),
443 for j
in range(2, 5):
444 tests
.append([VT("S1",
445 [VT("float[{}]".format(j
)),
448 tests
.append([VT("S1", [VT(name_arr
[i
] + "[3]")])])
450 tests
.append([VT("S1",
451 [VT("S2[3]", [VT(name_arr
[i
]), VT("float")])])])
453 tests
.append([VT("S1",
454 [VT("S2", [VT(name_arr
[i
])])])])
456 for i
in range(1, 2):
457 tests
.append([VT("S1",
461 VT(name_arr
[i
])])])])])
463 tests
.append([VT("S1",
467 VT(name_arr
[i
])])])])])
469 tests
.append([VT("S1[2]",
472 VT(name_arr
[i
])])])])])
475 do_test_permutations(t
, glsl_version
, extensions
, tests_path
)
479 for i
in range(1, 2):
480 tests
.append([VT("S1",
481 [VT(name_arr
[i
] + "[3][2]")])])
482 for i
in range(1, 2):
483 for j
in range(1, 4):
484 tests
.append([VT("S1",
485 [VT(FLOAT_VEC_TYPES
[j
]),
486 VT(name_arr
[i
] + "[3][2]")])])
488 for i
in range(1, 2):
489 for j
in range(1, 4):
490 tests
.append([VT("S1", [VT("S2[2][2]",
491 [VT(FLOAT_VEC_TYPES
[j
]),
492 VT(name_arr
[i
])])])])
494 for i
in range(3, 4):
495 tests
.append([VT("S1", [VT(name_arr
[i
] + "[2][2]")])])
498 do_test_permutations(t
, glsl_version
,
499 extensions
+ ["GL_ARB_arrays_of_arrays"],
503 def do_fp64_specific_tests():
506 for t
in DOUBLE_MAT_TYPES
:
507 tests
.append([VT("S1", [VT(t
)])])
509 for t
in ["dmat2x2", "dmat2x3", "dmat2x4", "dmat3x2", "dmat3x3"]:
510 for j
in range(1, 4):
511 tests
.append([VT("S1", [VT(FLOAT_VEC_TYPES
[j
]), VT(t
)])])
513 for j
in range(1, 7):
514 tests
.append([VT("S1",
515 [VT("float[{}]".format(j
)), VT(t
)])])
517 for j
in range(1, 4):
518 tests
.append([VT("S1", [VT("S2[2]",
519 [VT(FLOAT_VEC_TYPES
[j
]),
522 tests
.append([VT("S1",
523 [VT("double"), VT("float"), VT("double[2]"),
524 VT("float[3]"), VT("dmat2x2")])])
526 tests
.append([VT("S1",
527 [VT("S2", [VT("double")]),
528 VT("S3", [VT("float")]),
529 VT("S4", [VT("dmat3x3")])])])
532 do_test_permutations(t
, 150, ["GL_ARB_gpu_shader_fp64"], fp64_ext_path
)
533 do_test_permutations(t
, 400, [], fp64_core_path
)
536 do_common_64bit_tests(400, [], DOUBLE_VEC_TYPES
, fp64_core_path
)
537 do_common_64bit_tests(150, ["GL_ARB_gpu_shader_fp64"], DOUBLE_VEC_TYPES
,
539 do_common_64bit_tests(150, ["GL_ARB_gpu_shader_int64"], INT64_VEC_TYPES
,
541 do_common_64bit_tests(150, ["GL_ARB_gpu_shader_int64"], UINT64_VEC_TYPES
,
544 do_fp64_specific_tests()