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