• 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::__anon2de807f00111::Case46 	Case(const char* b, const char* d) : basename(b), description(d), requirements() { }
Casevkt::SpirVAssembly::__anon2de807f00111::Case47 	Case(const char* b, const char* d, const std::vector<std::string>& e) : basename(b), description(d), requirements(e) { }
48 	const char *basename;
49 	const char *description;
50 	// Additional Vulkan requirements, if any.
51 	std::vector<std::string> requirements;
52 };
53 struct CaseGroup
54 {
CaseGroupvkt::SpirVAssembly::__anon2de807f00111::CaseGroup55 	CaseGroup(const char* the_data_dir, const char* the_subdir) : data_dir(the_data_dir), subdir(the_subdir) { }
addvkt::SpirVAssembly::__anon2de807f00111::CaseGroup56 	void add(const char* basename, const char* description)
57 	{
58 		cases.push_back(Case(basename, description));
59 	}
addvkt::SpirVAssembly::__anon2de807f00111::CaseGroup60 	void add(const char* basename, const char* description, const std::vector<std::string>& requirements)
61 	{
62 		cases.push_back(Case(basename, description, requirements));
63 	}
64 
65 	const char* data_dir;
66 	const char* subdir;
67 	std::vector<Case> cases;
68 };
69 
70 
addTestsForAmberFiles(tcu::TestCaseGroup * tests,CaseGroup group)71 void addTestsForAmberFiles (tcu::TestCaseGroup* tests, CaseGroup group)
72 {
73 #ifndef CTS_USES_VULKANSC
74 	tcu::TestContext& testCtx = tests->getTestContext();
75 	const std::string data_dir(group.data_dir);
76 	const std::string subdir(group.subdir);
77 	const std::string category = data_dir + "/" + subdir;
78 	std::vector<Case> cases(group.cases);
79 	vk::SpirVAsmBuildOptions asm_options(VK_MAKE_API_VERSION(0, 1, 1, 0), vk::SPIRV_VERSION_1_4);
80 	asm_options.supports_VK_KHR_spirv_1_4 = true;
81 
82 	for (unsigned i = 0; i < cases.size() ; ++i)
83 	{
84 
85 		const std::string file = std::string(cases[i].basename) + ".amber";
86 		cts_amber::AmberTestCase *testCase = cts_amber::createAmberTestCase(testCtx,
87 																			cases[i].basename,
88 																			cases[i].description,
89 																			category.c_str(),
90 																			file);
91 		DE_ASSERT(testCase != DE_NULL);
92 		// Add Vulkan extension requirements.
93 		// VK_KHR_spirv_1_4 requires Vulkan 1.1, which includes many common extensions.
94 		// So for, example, these tests never have to request VK_KHR_storage_buffer_storage_class,
95 		// or VK_KHR_variable_pointers since those extensions were promoted to core features
96 		// in Vulkan 1.1.  Note that feature bits may still be optional.
97 		testCase->addRequirement("VK_KHR_spirv_1_4");
98 		// The tests often use StorageBuffer storage class.
99 		// We do not have to request VK_KHR_storage_buffer_storage_class because that extension
100 		// is about enabling use of SPV_KHR_storage_buffer_storage_class.  But SPIR-V 1.4 allows
101 		// use of StorageBuffer storage class without any further declarations of extensions
102 		// or capabilities.  This will also hold for tests that use features introduced by
103 		// extensions folded into SPIR-V 1.4 or earlier, and which don't require extra capabilities
104 		// to be enabled by Vulkan.  Other examples are functionality in SPV_GOOGLE_decorate_string,
105 		// SPV_GOOGLE_hlsl_functionality1, and SPV_KHR_no_integer_wrap_decoration.
106 		const std::vector<std::string>& reqmts = cases[i].requirements;
107 		for (size_t r = 0; r < reqmts.size() ; ++r)
108 		{
109 			testCase->addRequirement(reqmts[r]);
110 		}
111 
112 		testCase->setSpirVAsmBuildOptions(asm_options);
113 		tests->addChild(testCase);
114 	}
115 #else
116 	DE_UNREF(tests);
117 	DE_UNREF(group);
118 #endif
119 }
120 
121 } // anonymous
122 
createSpirvVersion1p4Group(tcu::TestContext & testCtx)123 tcu::TestCaseGroup* createSpirvVersion1p4Group (tcu::TestContext& testCtx)
124 {
125 	de::MovePtr<tcu::TestCaseGroup> spirv1p4Tests(new tcu::TestCaseGroup(testCtx, "spirv1p4", "SPIR-V 1.4 new features"));
126 
127 	// Location of the Amber script files under the data/vulkan/amber source tree.
128 	const char* data_dir = "spirv_assembly/instruction/spirv1p4";
129 
130 	// Set up features used for various tests.
131 	std::vector<std::string> Geom;
132 	Geom.push_back("Features.geometryShader");
133 
134 	std::vector<std::string> Tess;
135 	Tess.push_back("Features.tessellationShader");
136 
137 	std::vector<std::string> Varptr_ssbo;
138 	Varptr_ssbo.push_back("VariablePointerFeatures.variablePointersStorageBuffer");
139 
140 	std::vector<std::string> Varptr_full = Varptr_ssbo;
141 	Varptr_full.push_back("VariablePointerFeatures.variablePointers");
142 
143 	std::vector<std::string> Int16;
144 	Int16.push_back("Features.shaderInt16");
145 
146 	std::vector<std::string> Int16_storage = Int16;
147 	Int16_storage.push_back("VK_KHR_16bit_storage");
148 	Int16_storage.push_back("Storage16BitFeatures.storageBuffer16BitAccess");
149 
150 	std::vector<std::string> Int64;
151 	Int64.push_back("Features.shaderInt64");
152 
153 	// Define test groups
154 
155 	CaseGroup group(data_dir, "opcopylogical");
156 	group.add("different_matrix_layout","different matrix layout");
157 	group.add("different_matrix_strides","different matrix strides");
158 	group.add("nested_arrays_different_inner_stride","nested_arrays_different_inner_stride");
159 	group.add("nested_arrays_different_outer_stride","nested_arrays_different_inner_stride");
160 	group.add("nested_arrays_different_strides","nested_arrays_different_strides");
161 	group.add("same_array_two_ids","same array two ids");
162 	group.add("same_struct_two_ids","same struct two ids");
163 	group.add("ssbo_to_ubo","ssbo_to_ubo");
164 	group.add("two_arrays_different_stride_1","two_arrays_different_stride_1");
165 	group.add("two_arrays_different_stride_2","two_arrays_different_stride_2");
166 	group.add("ubo_to_ssbo","ubo_to_ssbo");
167 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opcopylogical", "OpCopyLogical", addTestsForAmberFiles, group));
168 
169 	group = CaseGroup(data_dir, "opptrdiff");
170 	group.add("ssbo_comparisons_diff", "pointer diff within an SSBO", Varptr_ssbo);
171 	group.add("variable_pointers_vars_ssbo_2_diff", "pointer diff in SSBO with full VariablePointers", Varptr_ssbo);
172 	group.add("variable_pointers_vars_ssbo_diff", "pointer diff in SSBO, stored in private var", Varptr_ssbo);
173 	group.add("variable_pointers_vars_wg_diff", "pointer diff in workgroup storage, stored in private var", Varptr_full);
174 	group.add("wg_comparisons_diff", "pointer diff in workgroup storage", Varptr_full);
175 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrdiff", "OpPtrDiff", addTestsForAmberFiles, group));
176 
177 	group = CaseGroup(data_dir, "opptrequal");
178 	group.add("different_ssbos_equal", "ptr equal against different SSBO variables", Varptr_full);
179 	group.add("different_wgs_equal", "ptr equal against different WG variables", Varptr_full);
180 	group.add("null_comparisons_ssbo_equal", "ptr equal null in SSBO", Varptr_ssbo);
181 	group.add("null_comparisons_wg_equal", "ptr equal null in Workgrop", Varptr_full);
182 	group.add("ssbo_comparisons_equal", "ptr equal in SSBO", Varptr_ssbo);
183 	group.add("variable_pointers_ssbo_2_equal", "ptr equal in SSBO, store pointers in Function var", Varptr_full);
184 	group.add("variable_pointers_ssbo_equal", "ptr equal in SSBO", Varptr_ssbo);
185 	group.add("variable_pointers_vars_ssbo_equal", "ptr equal in SSBO, store pointers in Private var ", Varptr_ssbo);
186 	group.add("simple_variable_pointers_ptr_equal", "ptr equal between simple data primitives in SSBOs", Varptr_ssbo);
187 	group.add("variable_pointers_vars_wg_equal", "ptr equal in Workgrop, store pointers in Private var", Varptr_full);
188 	group.add("variable_pointers_wg_equal", "ptr equal in Workgrop", Varptr_full);
189 	group.add("wg_comparisons_equal", "ptr equal in Workgrop", Varptr_full);
190 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrequal", "OpPtrEqual", addTestsForAmberFiles, group));
191 
192 	group = CaseGroup(data_dir, "opptrnotequal");
193 	group.add("different_ssbos_not_equal", "ptr not equal against different SSBO variables", Varptr_full);
194 	group.add("different_wgs_not_equal", "ptr not equal against different WG variables", Varptr_full);
195 	group.add("null_comparisons_ssbo_not_equal", "ptr not equal null SSBO", Varptr_ssbo);
196 	group.add("null_comparisons_wg_not_equal", "ptr not equal null SSBO", Varptr_full);
197 	group.add("ssbo_comparisons_not_equal", "ptr not equal SSBO", Varptr_ssbo);
198 	group.add("variable_pointers_ssbo_2_not_equal", "ptr not equal SSBO, store pointer in Function var", Varptr_full);
199 	group.add("variable_pointers_ssbo_not_equal", "ptr not equal SSBO, pointer from function return", Varptr_ssbo);
200 	group.add("simple_variable_pointers_ptr_not_equal", "ptr not equal between simple data primitives in SSBOs", Varptr_ssbo);
201 	group.add("variable_pointers_vars_ssbo_not_equal", "ptr not equal SSBO, store pointer in Private var", Varptr_ssbo);
202 	group.add("variable_pointers_vars_wg_not_equal", "ptr not equal Workgroup, store pointer in Private var", Varptr_full);
203 	group.add("variable_pointers_wg_not_equal", "ptr not equal Workgroup", Varptr_full);
204 	group.add("wg_comparisons_not_equal", "ptr not equal Workgroup", Varptr_full);
205 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opptrnotequal", "OpPtrNotEqual", addTestsForAmberFiles, group));
206 
207 	group = CaseGroup(data_dir, "opcopymemory");
208 	group.add("different_alignments", "different alignments");
209 	group.add("no_source_access_operands", "no source access operands");
210 	group.add("no_target_access_operands", "no target access operands");
211 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opcopymemory", "OpCopyMemory 2 memory access operands", addTestsForAmberFiles, group));
212 
213 	group = CaseGroup(data_dir, "uniformid");
214 	group.add("partially_active_uniform_id","workgroup uniform load result at consumption, in nonuniform control flow");
215 	group.add("subgroup_cfg_uniform_id","subgroup uniform compare result inside control flow"); // Assumes subgroup size <= LocalSize of 8
216 	group.add("subgroup_uniform","subgroup uniform load result"); // Assumes subgroup size <= LocalSize 8
217 	group.add("workgroup_cfg_uniform_id","workgroup uniform compare result");
218 	group.add("workgroup_uniform","workgroup uniform load result");
219 	spirv1p4Tests->addChild(createTestGroup(testCtx, "uniformid", "UniformId decoration", addTestsForAmberFiles, group));
220 
221 	group = CaseGroup(data_dir, "nonwritable");
222 	group.add("function_2_nonwritable", "NonWritable decorates Function variables");
223 	group.add("function_nonwritable", "NonWritable decorates 2 Function variables");
224 	group.add("non_main_function_nonwritable", "NonWritable decorates Function variable in non-entrypoint function");
225 	group.add("private_2_nonwritable", "NonWritable decorates Private variables");
226 	group.add("private_nonwritable", "NonWritable decorates 2 Private variables");
227 	spirv1p4Tests->addChild(createTestGroup(testCtx, "nonwritable", "NonWritable decoration", addTestsForAmberFiles, group));
228 
229 	group = CaseGroup(data_dir, "entrypoint");
230 	group.add("comp_pc_entry_point", "push constant on compute shader entry point");
231 	group.add("comp_ssbo_entry_point", "SSBO on compute shader entry point");
232 	group.add("comp_ubo_entry_point", "UBO on compute shader entry point");
233 	group.add("comp_workgroup_entry_point", "Workgroup var on compute shader entry point");
234 	group.add("frag_pc_entry_point", "push constant on fragment shader entry point");
235 	group.add("frag_ssbo_entry_point", "SSBO on fragment shader entry point");
236 	group.add("frag_ubo_entry_point", "UBO on fragment shader entry point");
237 	group.add("geom_pc_entry_point", "push constant on geometry shader entry point", Geom);
238 	group.add("geom_ssbo_entry_point", "SSBO on geometry shader entry point", Geom);
239 	group.add("geom_ubo_entry_point", "UBO on geometry shader entry point", Geom);
240 	group.add("tess_con_pc_entry_point", "push constant on tess control shader entry point", Tess);
241 	group.add("tess_con_ssbo_entry_point", "SSBO on tess control shader entry point", Tess);
242 	group.add("tess_con_ubo_entry_point", "UBO on tess control shader entry point", Tess);
243 	group.add("tess_eval_pc_entry_point", "push constant on tess eval shader entry point", Tess);
244 	group.add("tess_eval_ssbo_entry_point", "SSBO on tess eval shader entry point", Tess);
245 	group.add("tess_eval_ubo_entry_point", "UBO on tess eval shader entry point", Tess);
246 	group.add("vert_pc_entry_point", "push constant on vertex shader entry point");
247 	group.add("vert_ssbo_entry_point", "SSBO on vertex shader entry point");
248 	group.add("vert_ubo_entry_point", "UBO on vertex shader entry point");
249 	spirv1p4Tests->addChild(createTestGroup(testCtx, "entrypoint", "EntryPoint lists all module-scope variables", addTestsForAmberFiles, group));
250 
251 	group = CaseGroup(data_dir, "hlsl_functionality1");
252 	group.add("counter_buffer", "CounterBuffer decoration");
253 	group.add("decorate_string", "OpDecorateString");
254 	group.add("member_decorate_string", "OpMemberDecorateString");
255 	spirv1p4Tests->addChild(createTestGroup(testCtx, "hlsl_functionality1", "Features in SPV_GOOGLE_hlsl_functionality1 in SPIR-V 1.4", addTestsForAmberFiles, group));
256 
257 	group = CaseGroup(data_dir, "loop_control");
258 	group.add("iteration_multiple", "Loop control IterationMultiple");
259 	group.add("max_iterations", "Loop control MaxIterations");
260 	group.add("min_iterations", "Loop control MinIterations");
261 	group.add("partial_count", "Loop control PartialCount");
262 	group.add("peel_count", "Loop control PeelCount");
263 	spirv1p4Tests->addChild(createTestGroup(testCtx, "loop_control", "SPIR-V 1.4 loop controls", addTestsForAmberFiles, group));
264 
265 	group = CaseGroup(data_dir, "opselect");
266 	group.add("array_select", "OpSelect arrays, new in SPIR-V 1.4");
267 	group.add("array_stride_select", "OpSelect arrays with non-standard strides, new in SPIR-V 1.4");
268 	group.add("nested_array_select", "OpSelect structs with nested arrays, new in SPIR-V 1.4");
269 	group.add("nested_struct_select", "OpSelect structs with nested structs, new in SPIR-V 1.4");
270 	group.add("scalar_select", "OpSelect scalars, verify SPIR-V 1.0");
271 	group.add("ssbo_pointers_2_select", "OpSelect SSBO pointers to different buffers, verify SPIR-V 1.0", Varptr_full);
272 	group.add("ssbo_pointers_select", "OpSelect SSBO pointers to same buffer, verify SPIR-V 1.0", Varptr_ssbo);
273 	group.add("struct_select", "OpSelect structs, new in SPIR-V 1.4");
274 	group.add("vector_element_select", "OpSelect vector with vector selector, verify SPIR-V 1.0");
275 	group.add("vector_select", "OpSelect vector with scalar selector, new in SPIR-V 1.4");
276 	group.add("wg_pointers_2_select", "OpSelect Workgroup pointers to different buffers, verify SPIR-V 1.0", Varptr_full);
277 	group.add("wg_pointers_select", "OpSelect Workgroup pointers to same buffer, verify SPIR-V 1.0", Varptr_full);
278 	spirv1p4Tests->addChild(createTestGroup(testCtx, "opselect", "SPIR-V 1.4 OpSelect more cases", addTestsForAmberFiles, group));
279 
280 	group = CaseGroup(data_dir, "uconvert");
281 	group.add("spec_const_opt_extend_16_64_bit","uconvert small to int64", Int64);
282 	group.add("spec_const_opt_extend_16","uconvert from int16", Int16);
283 	group.add("spec_const_opt_extend_251658240_64_bits","uconvert large to int64", Int64);
284 	group.add("spec_const_opt_extend_61440", "uconvert large from int16", Int16);
285 	group.add("spec_const_opt_truncate_16_64_bit", "uconvert from int64", Int64);
286 	group.add("spec_const_opt_truncate_16", "uconvert small to int16", Int16_storage);
287 	group.add("spec_const_opt_truncate_983040", "uconvert large to int16", Int16_storage);
288 	group.add("spec_const_opt_zero_extend_n4096", "uconvert negative from int16", Int16);
289 	spirv1p4Tests->addChild(createTestGroup(testCtx, "uconvert", "SPIR-V 1.4 UConvert in OpSpecConstantOp", addTestsForAmberFiles, group));
290 
291 	group = CaseGroup(data_dir, "wrap");
292 	group.add("no_signed_wrap", "Accept NoSignedWrap decoration");
293 	group.add("no_unsigned_wrap", "Accept NoUnsignedWrap decoration");
294 	spirv1p4Tests->addChild(createTestGroup(testCtx, "wrap", "SPIR-V 1.4 integer wrap decorations", addTestsForAmberFiles, group));
295 
296 	return spirv1p4Tests.release();
297 }
298 
299 } // SpirVAssembly
300 } // vkt
301