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 << "#version 310 es\n"
72 "layout(local_size_x=1) in;\n"
73 "void main (void)\n"
74 "{\n"
75 "}\n";
76
77 sources.glslSources.add("comp") << glu::ComputeSource(computeSource.str());
78 }
79
testComputeDerivativeByHandle(Context & context,bool useMaintenance5)80 tcu::TestStatus testComputeDerivativeByHandle(Context &context, bool useMaintenance5)
81 {
82 const DeviceInterface &vk = context.getDeviceInterface();
83 const VkDevice vkDevice = context.getDevice();
84 Move<VkShaderModule> shaderModule = createShaderModule(vk, vkDevice, context.getBinaryCollection().get("comp"), 0);
85
86 Move<VkPipelineLayout> layout = makePipelineLayout(vk, vkDevice);
87
88 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
89 DE_NULL,
90 VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
91 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, 0,
92 VK_SHADER_STAGE_COMPUTE_BIT, shaderModule.get(), "main", DE_NULL},
93 layout.get(),
94 0,
95 -1};
96
97 #ifndef CTS_USES_VULKANSC
98 VkPipelineCreateFlags2CreateInfoKHR flags2CreateInfo = initVulkanStructure();
99 if (useMaintenance5)
100 {
101 flags2CreateInfo.flags = VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR;
102 cpci.flags = 0;
103 cpci.pNext = &flags2CreateInfo;
104 }
105 #else
106 DE_UNREF(useMaintenance5);
107 #endif // CTS_USES_VULKANSC
108
109 Move<VkPipeline> basePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &cpci);
110
111 // Create second (identical) pipeline based on first
112 cpci.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
113 cpci.basePipelineHandle = basePipeline.get();
114
115 #ifndef CTS_USES_VULKANSC
116 if (useMaintenance5)
117 {
118 flags2CreateInfo.flags = VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR;
119 cpci.flags = 0;
120 }
121 #endif // CTS_USES_VULKANSC
122
123 Move<VkPipeline> derivedPipeline = createComputePipeline(vk, vkDevice, DE_NULL, &cpci);
124
125 // If we got here without crashing, success.
126 return tcu::TestStatus::pass("OK");
127 }
128
testComputeDerivativeByIndex(Context & context,bool)129 tcu::TestStatus testComputeDerivativeByIndex(Context &context, bool)
130 {
131 const DeviceInterface &vk = context.getDeviceInterface();
132 const VkDevice vkDevice = context.getDevice();
133 Move<VkShaderModule> shaderModule = createShaderModule(vk, vkDevice, context.getBinaryCollection().get("comp"), 0);
134
135 Move<VkPipelineLayout> layout = makePipelineLayout(vk, vkDevice);
136
137 VkComputePipelineCreateInfo cpci[2] = {{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
138 DE_NULL,
139 VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
140 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, 0,
141 VK_SHADER_STAGE_COMPUTE_BIT, shaderModule.get(), "main", DE_NULL},
142 layout.get(),
143 0,
144 -1},
145 {
146 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
147 DE_NULL,
148 VK_PIPELINE_CREATE_DERIVATIVE_BIT,
149 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, 0,
150 VK_SHADER_STAGE_COMPUTE_BIT, shaderModule.get(), "main", DE_NULL},
151 layout.get(),
152 0,
153 0,
154 }};
155
156 std::vector<VkPipeline> rawPipelines(2);
157 vk.createComputePipelines(vkDevice, 0, 2, cpci, DE_NULL, rawPipelines.data());
158
159 for (uint32_t i = 0; i < rawPipelines.size(); i++)
160 {
161 vk.destroyPipeline(vkDevice, rawPipelines[i], DE_NULL);
162 }
163
164 // If we got here without crashing, success.
165 return tcu::TestStatus::pass("OK");
166 }
167
168 } // namespace
169
createDerivativeTests(tcu::TestContext & testCtx)170 tcu::TestCaseGroup *createDerivativeTests(tcu::TestContext &testCtx)
171 {
172 de::MovePtr<tcu::TestCaseGroup> derivativeTests(new tcu::TestCaseGroup(testCtx, "derivative"));
173 de::MovePtr<tcu::TestCaseGroup> computeTests(new tcu::TestCaseGroup(testCtx, "compute"));
174
175 addFunctionCaseWithPrograms(computeTests.get(), "derivative_by_handle", initComputeDerivativePrograms,
176 testComputeDerivativeByHandle, false);
177 #ifndef CTS_USES_VULKANSC
178 addFunctionCaseWithPrograms(computeTests.get(), "derivative_by_handle_maintenance5", checkSupport,
179 initComputeDerivativePrograms, testComputeDerivativeByHandle, true);
180 #endif // CTS_USES_VULKANSC
181 addFunctionCaseWithPrograms(computeTests.get(), "derivative_by_index", initComputeDerivativePrograms,
182 testComputeDerivativeByIndex, false);
183
184 derivativeTests->addChild(computeTests.release());
185 return derivativeTests.release();
186 }
187
188 } // namespace pipeline
189
190 } // namespace vkt
191