• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Google LLC
6  * Copyright (c) 2019 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Test new features in SPIR-V 1.4.
23  *//*--------------------------------------------------------------------*/
24 
25 #include <string>
26 #include <vector>
27 #include <amber/amber.h>
28 
29 #include "tcuDefs.hpp"
30 
31 #include "vkDefs.hpp"
32 #include "vktTestGroupUtil.hpp"
33 #include "vktAmberTestCase.hpp"
34 #include "vktSpvAsmSpirvVersion1p4Tests.hpp"
35 #include "vktTestGroupUtil.hpp"
36 
37 namespace vkt
38 {
39 namespace SpirVAssembly
40 {
41 namespace
42 {
43 
44 struct Case
45 {
Casevkt::SpirVAssembly::__anonc4f0ce320111::Case46 	Case(const char* b) : basename(b), requirements() { }
Casevkt::SpirVAssembly::__anonc4f0ce320111::Case47 	Case(const char* b, const std::vector<std::string>& e) : basename(b), requirements(e) { }
48 	const char *basename;
49 	// Additional Vulkan requirements, if any.
50 	std::vector<std::string> requirements;
51 };
52 struct CaseGroup
53 {
CaseGroupvkt::SpirVAssembly::__anonc4f0ce320111::CaseGroup54 	CaseGroup(const char* the_data_dir, const char* the_subdir) : data_dir(the_data_dir), subdir(the_subdir) { }
addvkt::SpirVAssembly::__anonc4f0ce320111::CaseGroup55 	void add(const char* basename)
56 	{
57 		cases.push_back(Case(basename));
58 	}
addvkt::SpirVAssembly::__anonc4f0ce320111::CaseGroup59 	void add(const char* basename, const std::vector<std::string>& requirements)
60 	{
61 		cases.push_back(Case(basename, requirements));
62 	}
63 
64 	const char* data_dir;
65 	const char* subdir;
66 	std::vector<Case> cases;
67 };
68 
69 
addTestsForAmberFiles(tcu::TestCaseGroup * tests,CaseGroup group)70 void addTestsForAmberFiles (tcu::TestCaseGroup* tests, CaseGroup group)
71 {
72 #ifndef CTS_USES_VULKANSC
73 	tcu::TestContext& testCtx = tests->getTestContext();
74 	const std::string data_dir(group.data_dir);
75 	const std::string subdir(group.subdir);
76 	const std::string category = data_dir + "/" + subdir;
77 	std::vector<Case> cases(group.cases);
78 	vk::SpirVAsmBuildOptions asm_options(VK_MAKE_API_VERSION(0, 1, 1, 0), vk::SPIRV_VERSION_1_4);
79 	asm_options.supports_VK_KHR_spirv_1_4 = true;
80 
81 	for (unsigned i = 0; i < cases.size() ; ++i)
82 	{
83 
84 		const std::string file = std::string(cases[i].basename) + ".amber";
85 		cts_amber::AmberTestCase *testCase = cts_amber::createAmberTestCase(testCtx,
86 																			cases[i].basename,
87 																			category.c_str(),
88 																			file);
89 		DE_ASSERT(testCase != DE_NULL);
90 		// Add Vulkan extension requirements.
91 		// VK_KHR_spirv_1_4 requires Vulkan 1.1, which includes many common extensions.
92 		// So for, example, these tests never have to request VK_KHR_storage_buffer_storage_class,
93 		// or VK_KHR_variable_pointers since those extensions were promoted to core features
94 		// in Vulkan 1.1.  Note that feature bits may still be optional.
95 		testCase->addRequirement("VK_KHR_spirv_1_4");
96 		// The tests often use StorageBuffer storage class.
97 		// We do not have to request VK_KHR_storage_buffer_storage_class because that extension
98 		// is about enabling use of SPV_KHR_storage_buffer_storage_class.  But SPIR-V 1.4 allows
99 		// use of StorageBuffer storage class without any further declarations of extensions
100 		// or capabilities.  This will also hold for tests that use features introduced by
101 		// extensions folded into SPIR-V 1.4 or earlier, and which don't require extra capabilities
102 		// to be enabled by Vulkan.  Other examples are functionality in SPV_GOOGLE_decorate_string,
103 		// SPV_GOOGLE_hlsl_functionality1, and SPV_KHR_no_integer_wrap_decoration.
104 		const std::vector<std::string>& reqmts = cases[i].requirements;
105 		for (size_t r = 0; r < reqmts.size() ; ++r)
106 		{
107 			testCase->addRequirement(reqmts[r]);
108 		}
109 
110 		testCase->setSpirVAsmBuildOptions(asm_options);
111 		tests->addChild(testCase);
112 	}
113 #else
114 	DE_UNREF(tests);
115 	DE_UNREF(group);
116 #endif
117 }
118 
119 } // anonymous
120 
createSpirvVersion1p4Group(tcu::TestContext & testCtx)121 tcu::TestCaseGroup* createSpirvVersion1p4Group (tcu::TestContext& testCtx)
122 {
123 	// SPIR-V 1.4 new features
124 	de::MovePtr<tcu::TestCaseGroup> spirv1p4Tests(new tcu::TestCaseGroup(testCtx, "spirv1p4"));
125 
126 	// Location of the Amber script files under the data/vulkan/amber source tree.
127 	const char* data_dir = "spirv_assembly/instruction/spirv1p4";
128 
129 	// Set up features used for various tests.
130 	std::vector<std::string> Geom;
131 	Geom.push_back("Features.geometryShader");
132 
133 	std::vector<std::string> Tess;
134 	Tess.push_back("Features.tessellationShader");
135 
136 	std::vector<std::string> Varptr_ssbo;
137 	Varptr_ssbo.push_back("VariablePointerFeatures.variablePointersStorageBuffer");
138 
139 	std::vector<std::string> Varptr_full = Varptr_ssbo;
140 	Varptr_full.push_back("VariablePointerFeatures.variablePointers");
141 
142 	std::vector<std::string> Int16;
143 	Int16.push_back("Features.shaderInt16");
144 
145 	std::vector<std::string> Int16_storage = Int16;
146 	Int16_storage.push_back("VK_KHR_16bit_storage");
147 	Int16_storage.push_back("Storage16BitFeatures.storageBuffer16BitAccess");
148 
149 	std::vector<std::string> Int64;
150 	Int64.push_back("Features.shaderInt64");
151 
152 	// Define test groups
153 
154 	CaseGroup group(data_dir, "opcopylogical");
155 	// different matrix layout
156 	group.add("different_matrix_layout");
157 	// different matrix strides
158 	group.add("different_matrix_strides");
159 	// nested_arrays_different_inner_stride
160 	group.add("nested_arrays_different_inner_stride");
161 	// nested_arrays_different_inner_stride
162 	group.add("nested_arrays_different_outer_stride");
163 	// nested_arrays_different_strides
164 	group.add("nested_arrays_different_strides");
165 	// same array two ids
166 	group.add("same_array_two_ids");
167 	// same struct two ids
168 	group.add("same_struct_two_ids");
169 	// ssbo_to_ubo
170 	group.add("ssbo_to_ubo");
171 	// two_arrays_different_stride_1
172 	group.add("two_arrays_different_stride_1");
173 	// two_arrays_different_stride_2
174 	group.add("two_arrays_different_stride_2");
175 	// ubo_to_ssbo
176 	group.add("ubo_to_ssbo");
177 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opcopylogical", addTestsForAmberFiles, group));
178 
179 	group = CaseGroup(data_dir, "opptrdiff");
180 	// pointer diff within an SSBO
181 	group.add("ssbo_comparisons_diff", Varptr_ssbo);
182 	// pointer diff in SSBO with full VariablePointers
183 	group.add("variable_pointers_vars_ssbo_2_diff", Varptr_ssbo);
184 	// pointer diff in SSBO, stored in private var
185 	group.add("variable_pointers_vars_ssbo_diff", Varptr_ssbo);
186 	// pointer diff in workgroup storage, stored in private var
187 	group.add("variable_pointers_vars_wg_diff", Varptr_full);
188 	// pointer diff in workgroup storage
189 	group.add("wg_comparisons_diff", Varptr_full);
190 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrdiff", addTestsForAmberFiles, group));
191 
192 	group = CaseGroup(data_dir, "opptrequal");
193 	// ptr equal against different SSBO variables
194 	group.add("different_ssbos_equal", Varptr_full);
195 	// ptr equal against different WG variables
196 	group.add("different_wgs_equal", Varptr_full);
197 	// ptr equal null in SSBO
198 	group.add("null_comparisons_ssbo_equal", Varptr_ssbo);
199 	// ptr equal null in Workgrop
200 	group.add("null_comparisons_wg_equal", Varptr_full);
201 	// ptr equal in SSBO
202 	group.add("ssbo_comparisons_equal", Varptr_ssbo);
203 	// ptr equal in SSBO, store pointers in Function var
204 	group.add("variable_pointers_ssbo_2_equal", Varptr_full);
205 	// ptr equal in SSBO
206 	group.add("variable_pointers_ssbo_equal", Varptr_ssbo);
207 	// ptr equal in SSBO, store pointers in Private var
208 	group.add("variable_pointers_vars_ssbo_equal", Varptr_ssbo);
209 	// ptr equal between simple data primitives in SSBOs
210 	group.add("simple_variable_pointers_ptr_equal", Varptr_ssbo);
211 	// ptr equal in Workgrop, store pointers in Private var
212 	group.add("variable_pointers_vars_wg_equal", Varptr_full);
213 	// ptr equal in Workgrop
214 	group.add("variable_pointers_wg_equal", Varptr_full);
215 	// ptr equal in Workgrop
216 	group.add("wg_comparisons_equal", Varptr_full);
217 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrequal", addTestsForAmberFiles, group));
218 
219 	group = CaseGroup(data_dir, "opptrnotequal");
220 	// ptr not equal against different SSBO variables
221 	group.add("different_ssbos_not_equal", Varptr_full);
222 	// ptr not equal against different WG variables
223 	group.add("different_wgs_not_equal", Varptr_full);
224 	// ptr not equal null SSBO
225 	group.add("null_comparisons_ssbo_not_equal", Varptr_ssbo);
226 	// ptr not equal null SSBO
227 	group.add("null_comparisons_wg_not_equal", Varptr_full);
228 	// ptr not equal SSBO
229 	group.add("ssbo_comparisons_not_equal", Varptr_ssbo);
230 	// ptr not equal SSBO, store pointer in Function var
231 	group.add("variable_pointers_ssbo_2_not_equal", Varptr_full);
232 	// ptr not equal SSBO, pointer from function return
233 	group.add("variable_pointers_ssbo_not_equal", Varptr_ssbo);
234 	// ptr not equal between simple data primitives in SSBOs
235 	group.add("simple_variable_pointers_ptr_not_equal", Varptr_ssbo);
236 	// ptr not equal SSBO, store pointer in Private var
237 	group.add("variable_pointers_vars_ssbo_not_equal", Varptr_ssbo);
238 	// ptr not equal Workgroup, store pointer in Private var
239 	group.add("variable_pointers_vars_wg_not_equal", Varptr_full);
240 	// ptr not equal Workgroup
241 	group.add("variable_pointers_wg_not_equal", Varptr_full);
242 	// ptr not equal Workgroup
243 	group.add("wg_comparisons_not_equal", Varptr_full);
244 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrnotequal", addTestsForAmberFiles, group));
245 
246 	group = CaseGroup(data_dir, "opcopymemory");
247 	// different alignments
248 	group.add("different_alignments");
249 	// no source access operands
250 	group.add("no_source_access_operands");
251 	// no target access operands
252 	group.add("no_target_access_operands");
253 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opcopymemory", addTestsForAmberFiles, group));
254 
255 	group = CaseGroup(data_dir, "uniformid");
256 	// workgroup uniform load result at consumption, in nonuniform control flow
257 	group.add("partially_active_uniform_id");
258 	// subgroup uniform compare result inside control flow
259 	group.add("subgroup_cfg_uniform_id"); // Assumes subgroup size <= LocalSize of 8
260 	// subgroup uniform load result
261 	group.add("subgroup_uniform"); // Assumes subgroup size <= LocalSize 8
262 	// workgroup uniform compare result
263 	group.add("workgroup_cfg_uniform_id");
264 	// workgroup uniform load result
265 	group.add("workgroup_uniform");
266 	spirv1p4Tests->addChild(createTestGroup(testCtx, "uniformid", addTestsForAmberFiles, group));
267 
268 	group = CaseGroup(data_dir, "nonwritable");
269 	// NonWritable decorates Function variables
270 	group.add("function_2_nonwritable");
271 	// NonWritable decorates 2 Function variables
272 	group.add("function_nonwritable");
273 	// NonWritable decorates Function variable in non-entrypoint function
274 	group.add("non_main_function_nonwritable");
275 	// NonWritable decorates Private variables
276 	group.add("private_2_nonwritable");
277 	// NonWritable decorates 2 Private variables
278 	group.add("private_nonwritable");
279 	spirv1p4Tests->addChild(createTestGroup(testCtx, "nonwritable", addTestsForAmberFiles, group));
280 
281 	group = CaseGroup(data_dir, "entrypoint");
282 	// push constant on compute shader entry point
283 	group.add("comp_pc_entry_point");
284 	// SSBO on compute shader entry point
285 	group.add("comp_ssbo_entry_point");
286 	// UBO on compute shader entry point
287 	group.add("comp_ubo_entry_point");
288 	// Workgroup var on compute shader entry point
289 	group.add("comp_workgroup_entry_point");
290 	// push constant on fragment shader entry point
291 	group.add("frag_pc_entry_point");
292 	// SSBO on fragment shader entry point
293 	group.add("frag_ssbo_entry_point");
294 	// UBO on fragment shader entry point
295 	group.add("frag_ubo_entry_point");
296 	// push constant on geometry shader entry point
297 	group.add("geom_pc_entry_point", Geom);
298 	// SSBO on geometry shader entry point
299 	group.add("geom_ssbo_entry_point", Geom);
300 	// UBO on geometry shader entry point
301 	group.add("geom_ubo_entry_point", Geom);
302 	// push constant on tess control shader entry point
303 	group.add("tess_con_pc_entry_point", Tess);
304 	// SSBO on tess control shader entry point
305 	group.add("tess_con_ssbo_entry_point", Tess);
306 	// UBO on tess control shader entry point
307 	group.add("tess_con_ubo_entry_point", Tess);
308 	// push constant on tess eval shader entry point
309 	group.add("tess_eval_pc_entry_point", Tess);
310 	// SSBO on tess eval shader entry point
311 	group.add("tess_eval_ssbo_entry_point", Tess);
312 	// UBO on tess eval shader entry point
313 	group.add("tess_eval_ubo_entry_point", Tess);
314 	// push constant on vertex shader entry point
315 	group.add("vert_pc_entry_point");
316 	// SSBO on vertex shader entry point
317 	group.add("vert_ssbo_entry_point");
318 	// UBO on vertex shader entry point
319 	group.add("vert_ubo_entry_point");
320 	// EntryPoint lists all module-scope variables
321 	spirv1p4Tests->addChild(createTestGroup(testCtx, "entrypoint", addTestsForAmberFiles, group));
322 
323 	group = CaseGroup(data_dir, "hlsl_functionality1");
324 	// CounterBuffer decoration
325 	group.add("counter_buffer");
326 	// OpDecorateString
327 	group.add("decorate_string");
328 	// OpMemberDecorateString
329 	group.add("member_decorate_string");
330 	// Features in SPV_GOOGLE_hlsl_functionality1 in SPIR-V 1.4
331 	spirv1p4Tests->addChild(createTestGroup(testCtx, "hlsl_functionality1", addTestsForAmberFiles, group));
332 
333 	group = CaseGroup(data_dir, "loop_control");
334 	// Loop control IterationMultiple
335 	group.add("iteration_multiple");
336 	// Loop control MaxIterations
337 	group.add("max_iterations");
338 	// Loop control MinIterations
339 	group.add("min_iterations");
340 	// Loop control PartialCount
341 	group.add("partial_count");
342 	// Loop control PeelCount
343 	group.add("peel_count");
344 	// SPIR-V 1.4 loop controls
345 	spirv1p4Tests->addChild(createTestGroup(testCtx, "loop_control", addTestsForAmberFiles, group));
346 
347 	group = CaseGroup(data_dir, "opselect");
348 	// OpSelect arrays, new in SPIR-V 1.4
349 	group.add("array_select");
350 	// OpSelect arrays with non-standard strides, new in SPIR-V 1.4
351 	group.add("array_stride_select");
352 	// OpSelect structs with nested arrays, new in SPIR-V 1.4
353 	group.add("nested_array_select");
354 	// OpSelect structs with nested structs, new in SPIR-V 1.4
355 	group.add("nested_struct_select");
356 	// OpSelect scalars, verify SPIR-V 1.0
357 	group.add("scalar_select");
358 	// OpSelect SSBO pointers to different buffers, verify SPIR-V 1.0
359 	group.add("ssbo_pointers_2_select", Varptr_full);
360 	// OpSelect SSBO pointers to same buffer, verify SPIR-V 1.0
361 	group.add("ssbo_pointers_select", Varptr_ssbo);
362 	// OpSelect structs, new in SPIR-V 1.4
363 	group.add("struct_select");
364 	// OpSelect vector with vector selector, verify SPIR-V 1.0
365 	group.add("vector_element_select");
366 	// OpSelect vector with scalar selector, new in SPIR-V 1.4
367 	group.add("vector_select");
368 	// OpSelect Workgroup pointers to different buffers, verify SPIR-V 1.0
369 	group.add("wg_pointers_2_select", Varptr_full);
370 	// OpSelect Workgroup pointers to same buffer, verify SPIR-V 1.0
371 	group.add("wg_pointers_select", Varptr_full);
372 	// SPIR-V 1.4 OpSelect more cases
373 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opselect", addTestsForAmberFiles, group));
374 
375 	group = CaseGroup(data_dir, "uconvert");
376 	// uconvert small to int64
377 	group.add("spec_const_opt_extend_16_64_bit", Int64);
378 	// uconvert from int16
379 	group.add("spec_const_opt_extend_16", Int16);
380 	// uconvert large to int64
381 	group.add("spec_const_opt_extend_251658240_64_bits", Int64);
382 	// uconvert large from int16
383 	group.add("spec_const_opt_extend_61440", Int16);
384 	// uconvert from int64
385 	group.add("spec_const_opt_truncate_16_64_bit", Int64);
386 	// uconvert small to int16
387 	group.add("spec_const_opt_truncate_16", Int16_storage);
388 	// uconvert large to int16
389 	group.add("spec_const_opt_truncate_983040", Int16_storage);
390 	// uconvert negative from int16
391 	group.add("spec_const_opt_zero_extend_n4096", Int16);
392 	// SPIR-V 1.4 UConvert in OpSpecConstantOp
393 	spirv1p4Tests->addChild(createTestGroup(testCtx, "uconvert", addTestsForAmberFiles, group));
394 
395 	group = CaseGroup(data_dir, "wrap");
396 	// Accept NoSignedWrap decoration
397 	group.add("no_signed_wrap");
398 	// Accept NoUnsignedWrap decoration
399 	group.add("no_unsigned_wrap");
400 	// SPIR-V 1.4 integer wrap decorations
401 	spirv1p4Tests->addChild(createTestGroup(testCtx, "wrap", addTestsForAmberFiles, group));
402 
403 	return spirv1p4Tests.release();
404 }
405 
406 } // SpirVAssembly
407 } // vkt
408