• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 Google LLC
6  * Copyright (c) 2020 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 VK_KHR_shader_terminate_invocation
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 "vktSpvAsmTerminateInvocationTests.hpp"
35 #include "vktTestGroupUtil.hpp"
36 
37 namespace vkt
38 {
39 namespace SpirVAssembly
40 {
41 namespace
42 {
43 
44 struct Case
45 {
Casevkt::SpirVAssembly::__anondd155b260111::Case46 	Case(const char* b, bool v) : basename(b), spv1p3(v), requirements() { }
Casevkt::SpirVAssembly::__anondd155b260111::Case47 	Case(const char* b, bool v, const std::vector<std::string>& e) : basename(b), spv1p3(v), requirements(e) { }
48 	const char *basename;
49 	bool spv1p3;
50 	// Additional Vulkan requirements, if any.
51 	std::vector<std::string> requirements;
52 };
53 struct CaseGroup
54 {
CaseGroupvkt::SpirVAssembly::__anondd155b260111::CaseGroup55 	CaseGroup(const char* the_data_dir) : data_dir(the_data_dir) { }
addvkt::SpirVAssembly::__anondd155b260111::CaseGroup56 	void add(const char* basename, bool spv1p3)
57 	{
58 		cases.push_back(Case(basename, spv1p3));
59 	}
addvkt::SpirVAssembly::__anondd155b260111::CaseGroup60 	void add(const char* basename, bool spv1p3, const std::vector<std::string>& requirements)
61 	{
62 		cases.push_back(Case(basename, spv1p3, requirements));
63 	}
64 
65 	const char* data_dir;
66 	std::vector<Case> cases;
67 };
68 
69 #ifndef CTS_USES_VULKANSC
70 
addTestsForAmberFiles(tcu::TestCaseGroup * tests,CaseGroup group)71 void addTestsForAmberFiles (tcu::TestCaseGroup* tests, CaseGroup group)
72 {
73 	tcu::TestContext& testCtx = tests->getTestContext();
74 	const std::string data_dir(group.data_dir);
75 	const std::string category = data_dir;
76 	std::vector<Case> cases(group.cases);
77 
78 	for (unsigned i = 0; i < cases.size() ; ++i)
79 	{
80 		deUint32 vulkan_version = cases[i].spv1p3 ? VK_MAKE_API_VERSION(0, 1, 1, 0) : VK_MAKE_API_VERSION(0, 1, 0, 0);
81 		vk::SpirvVersion spirv_version = cases[i].spv1p3 ? vk::SPIRV_VERSION_1_3 : vk::SPIRV_VERSION_1_0;
82 		vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
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 		testCase->addRequirement("VK_KHR_shader_terminate_invocation");
91 		const std::vector<std::string>& reqmts = cases[i].requirements;
92 		for (size_t r = 0; r < reqmts.size() ; ++r)
93 		{
94 			testCase->addRequirement(reqmts[r]);
95 		}
96 
97 		testCase->setSpirVAsmBuildOptions(asm_options);
98 		tests->addChild(testCase);
99 	}
100 }
101 
102 #endif // CTS_USES_VULKANSC
103 
104 } // anonymous
105 
createTerminateInvocationGroup(tcu::TestContext & testCtx)106 tcu::TestCaseGroup* createTerminateInvocationGroup(tcu::TestContext& testCtx)
107 {
108 	// VK_KHR_shader_terminate_invocation tests
109 	de::MovePtr<tcu::TestCaseGroup> terminateTests(new tcu::TestCaseGroup(testCtx, "terminate_invocation"));
110 
111 	const char* data_data = "spirv_assembly/instruction/terminate_invocation";
112 
113 	std::vector<std::string> Stores;
114 	Stores.push_back("Features.fragmentStoresAndAtomics");
115 
116 	std::vector<std::string> VarPtr;
117 	VarPtr.push_back("VariablePointerFeatures.variablePointersStorageBuffer");
118 	VarPtr.push_back("Features.fragmentStoresAndAtomics");
119 
120 	std::vector<std::string> Vote;
121 	Vote.push_back("SubgroupSupportedOperations.vote");
122 	Vote.push_back("SubgroupSupportedStages.fragment");
123 
124 	std::vector<std::string> Ballot;
125 	Ballot.push_back("SubgroupSupportedOperations.ballot");
126 	Ballot.push_back("SubgroupSupportedStages.fragment");
127 
128 	CaseGroup group(data_data);
129 	// no write to after calling terminate invocation
130 	group.add("no_output_write", false);
131 	// no write to output despite occurring before terminate invocation
132 	group.add("no_output_write_before_terminate", false);
133 	// no store to SSBO when it occurs after terminate invocation
134 	group.add("no_ssbo_store", false, Stores);
135 	// no atomic update to SSBO when it occurs after terminate invocation
136 	group.add("no_ssbo_atomic", false, Stores);
137 	// ssbo store commits when it occurs before terminate invocation
138 	group.add("ssbo_store_before_terminate", false, Stores);
139 	// no image write when it occurs after terminate invocation
140 	group.add("no_image_store", false, Stores);
141 	// no image atomic updates when it occurs after terminate invocation
142 	group.add("no_image_atomic", false, Stores);
143 	// null pointer should not be accessed by a load in a terminated invocation
144 	group.add("no_null_pointer_load", false, VarPtr);
145 	// null pointer should not be accessed by a store in a terminated invocation
146 	group.add("no_null_pointer_store", false, VarPtr);
147 	// out of bounds pointer should not be accessed by a load in a terminated invocation
148 	group.add("no_out_of_bounds_load", false, VarPtr);
149 	// out of bounds pointer should not be accessed by a store in a terminated invocation
150 	group.add("no_out_of_bounds_store", false, VarPtr);
151 	// out of bounds pointer should not be accessed by an atomic in a terminated invocation
152 	group.add("no_out_of_bounds_atomic", false, VarPtr);
153 	// "infinite" loop that calls terminate invocation
154 	group.add("terminate_loop", false);
155 	// checks that terminated invocations don't participate in the ballot
156 	group.add("subgroup_ballot", true, Ballot);
157 	// checks that a subgroup all does not include any terminated invocations
158 	group.add("subgroup_vote", true, Vote);
159 #ifndef CTS_USES_VULKANSC
160 	terminateTests->addChild(createTestGroup(testCtx, "terminate", addTestsForAmberFiles, group));
161 #endif // CTS_USES_VULKANSC
162 
163 	return terminateTests.release();
164 }
165 
166 } // SpirVAssembly
167 } // vkt
168