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