1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 * Copyright (c) 2018 Google 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 Pipeline Derivative Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineDerivativeTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineMakeUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deMemory.h"
45 #include "tcuTestLog.hpp"
46
47 #include <sstream>
48 #include <vector>
49
50 namespace vkt
51 {
52 namespace pipeline
53 {
54
55 using namespace vk;
56
57 namespace
58 {
59
checkSupport(Context & context,bool useMaintenance5)60 void checkSupport (Context& context, bool useMaintenance5)
61 {
62 if (useMaintenance5)
63 context.requireDeviceFunctionality("VK_KHR_maintenance5");
64 }
65
initComputeDerivativePrograms(SourceCollections & sources,bool)66 void initComputeDerivativePrograms (SourceCollections& sources, bool)
67 {
68 std::ostringstream computeSource;
69
70 // Trivial do-nothing compute shader
71 computeSource <<
72 "#version 310 es\n"
73 "layout(local_size_x=1) in;\n"
74 "void main (void)\n"
75 "{\n"
76 "}\n";
77
78 sources.glslSources.add("comp") << glu::ComputeSource(computeSource.str());
79 }
80
testComputeDerivativeByHandle(Context & context,bool useMaintenance5)81 tcu::TestStatus testComputeDerivativeByHandle (Context& context, bool useMaintenance5)
82 {
83 const DeviceInterface& vk = context.getDeviceInterface();
84 const VkDevice vkDevice = context.getDevice();
85 Move<VkShaderModule> shaderModule = createShaderModule(vk, vkDevice, context.getBinaryCollection().get("comp"), 0);
86
87 Move<VkPipelineLayout> layout = makePipelineLayout(vk, vkDevice);
88
89 VkComputePipelineCreateInfo cpci = {
90 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
91 DE_NULL,
92 VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
93 {
94 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
95 DE_NULL,
96 0,
97 VK_SHADER_STAGE_COMPUTE_BIT,
98 shaderModule.get(),
99 "main",
100 DE_NULL
101 },
102 layout.get(),
103 0,
104 -1
105 };
106
107 #ifndef CTS_USES_VULKANSC
108 VkPipelineCreateFlags2CreateInfoKHR flags2CreateInfo = initVulkanStructure();
109 if (useMaintenance5)
110 {
111 flags2CreateInfo.flags = VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR;
112 cpci.flags = 0;
113 cpci.pNext = &flags2CreateInfo;
114 }
115 #else
116 DE_UNREF(useMaintenance5);
117 #endif // CTS_USES_VULKANSC
118
119 Move<VkPipeline> basePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &cpci);
120
121 // Create second (identical) pipeline based on first
122 cpci.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
123 cpci.basePipelineHandle = basePipeline.get();
124
125 #ifndef CTS_USES_VULKANSC
126 if (useMaintenance5)
127 {
128 flags2CreateInfo.flags = VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR;
129 cpci.flags = 0;
130 }
131 #endif // CTS_USES_VULKANSC
132
133 Move<VkPipeline> derivedPipeline = createComputePipeline(vk, vkDevice, DE_NULL, &cpci);
134
135 // If we got here without crashing, success.
136 return tcu::TestStatus::pass("OK");
137 }
138
testComputeDerivativeByIndex(Context & context,bool)139 tcu::TestStatus testComputeDerivativeByIndex (Context& context, bool)
140 {
141 const DeviceInterface& vk = context.getDeviceInterface();
142 const VkDevice vkDevice = context.getDevice();
143 Move<VkShaderModule> shaderModule = createShaderModule(vk, vkDevice, context.getBinaryCollection().get("comp"), 0);
144
145 Move<VkPipelineLayout> layout = makePipelineLayout(vk, vkDevice);
146
147 VkComputePipelineCreateInfo cpci[2] = { {
148 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
149 DE_NULL,
150 VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
151 {
152 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
153 DE_NULL,
154 0,
155 VK_SHADER_STAGE_COMPUTE_BIT,
156 shaderModule.get(),
157 "main",
158 DE_NULL
159 },
160 layout.get(),
161 0,
162 -1
163 }, {
164 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
165 DE_NULL,
166 VK_PIPELINE_CREATE_DERIVATIVE_BIT,
167 {
168 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
169 DE_NULL,
170 0,
171 VK_SHADER_STAGE_COMPUTE_BIT,
172 shaderModule.get(),
173 "main",
174 DE_NULL
175 },
176 layout.get(),
177 0,
178 0,
179 } };
180
181 std::vector<VkPipeline> rawPipelines(2);
182 vk.createComputePipelines(vkDevice, 0, 2, cpci, DE_NULL, rawPipelines.data());
183
184 for (deUint32 i = 0; i < rawPipelines.size(); i++) {
185 vk.destroyPipeline(vkDevice, rawPipelines[i], DE_NULL);
186 }
187
188 // If we got here without crashing, success.
189 return tcu::TestStatus::pass("OK");
190 }
191
192 } // anonymous
193
createDerivativeTests(tcu::TestContext & testCtx)194 tcu::TestCaseGroup* createDerivativeTests (tcu::TestContext& testCtx)
195 {
196 de::MovePtr<tcu::TestCaseGroup> derivativeTests (new tcu::TestCaseGroup(testCtx, "derivative"));
197 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute"));
198
199 addFunctionCaseWithPrograms(computeTests.get(),
200 "derivative_by_handle",
201 initComputeDerivativePrograms,
202 testComputeDerivativeByHandle,
203 false);
204 #ifndef CTS_USES_VULKANSC
205 addFunctionCaseWithPrograms(computeTests.get(),
206 "derivative_by_handle_maintenance5",
207 checkSupport,
208 initComputeDerivativePrograms,
209 testComputeDerivativeByHandle,
210 true);
211 #endif // CTS_USES_VULKANSC
212 addFunctionCaseWithPrograms(computeTests.get(),
213 "derivative_by_index",
214 initComputeDerivativePrograms,
215 testComputeDerivativeByIndex,
216 false);
217
218 derivativeTests->addChild(computeTests.release());
219 return derivativeTests.release();
220 }
221
222 } // pipeline
223
224 } // vkt
225