1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Descriptor set tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiDescriptorSetTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 
27 #include "vkQueryUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkPrograms.hpp"
30 
31 namespace vkt
32 {
33 namespace api
34 {
35 
36 namespace
37 {
38 
39 using namespace std;
40 using namespace vk;
41 
42 // Descriptor set layout used to create a pipeline layout is destroyed prior to creating a pipeline
createPipelineLayoutDestroyDescriptorSetLayout(const DeviceInterface & vk,const VkDevice & device)43 Move<VkPipelineLayout> createPipelineLayoutDestroyDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device)
44 {
45 	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutInfo		=
46 	{
47 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
48 		DE_NULL,												// const void*							pNext;
49 		(VkDescriptorSetLayoutCreateFlags)0,					// VkDescriptorSetLayoutCreateFlags		flags;
50 		0u,														// deUint32								bindingCount;
51 		DE_NULL,												// const VkDescriptorSetLayoutBinding*	pBindings;
52 	};
53 
54 	Unique<VkDescriptorSetLayout>			descriptorSetLayout			(createDescriptorSetLayout(vk, device, &descriptorSetLayoutInfo));
55 
56 	const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
57 	{
58 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType;
59 		DE_NULL,												// const void*						pNext;
60 		(VkPipelineLayoutCreateFlags)0,							// VkPipelineLayoutCreateFlags		flags;
61 		1u,														// deUint32							setLayoutCount;
62 		&descriptorSetLayout.get(),								// const VkDescriptorSetLayout*		pSetLayouts;
63 		0u,														// deUint32							pushConstantRangeCount;
64 		DE_NULL													// const VkPushConstantRange*		pPushConstantRanges;
65 	};
66 
67 	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
68 }
69 
descriptorSetLayoutLifetimeGraphicsTest(Context & context)70 tcu::TestStatus descriptorSetLayoutLifetimeGraphicsTest (Context& context)
71 {
72 	const DeviceInterface&							vk								= context.getDeviceInterface();
73 	const VkDevice									device							= context.getDevice();
74 
75 	Unique<VkPipelineLayout>						pipelineLayout					(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
76 
77 	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
78 
79 	const VkPipelineShaderStageCreateInfo			shaderStageCreateInfo			=
80 	{
81 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
82 		DE_NULL,												// const void*						pNext;
83 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
84 		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits			stage;
85 		vertexShaderModule.get(),								// VkShaderModule					shader;
86 		"main",													// const char*						pName;
87 		DE_NULL,												// const VkSpecializationInfo*		pSpecializationInfo;
88 	};
89 
90 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
91 	{
92 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
93 		DE_NULL,													// const void*								pNext;
94 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags	flags;
95 		0u,															// deUint32									vertexBindingDescriptionCount;
96 		DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
97 		0u,															// deUint32									vertexAttributeDescriptionCount;
98 		DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
99 	};
100 
101 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
102 	{
103 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
104 		DE_NULL,														// const void*								pNext;
105 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
106 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology						topology;
107 		VK_FALSE														// VkBool32									primitiveRestartEnable;
108 	};
109 
110 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
111 	{
112 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
113 		DE_NULL,														// const void*								pNext;
114 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags	flags;
115 		VK_FALSE,														// VkBool32									depthClampEnable;
116 		VK_TRUE,														// VkBool32									rasterizerDiscardEnable;
117 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
118 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
119 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace								frontFace;
120 		VK_FALSE,														// VkBool32									depthBiasEnable;
121 		0.0f,															// float									depthBiasConstantFactor;
122 		0.0f,															// float									depthBiasClamp;
123 		0.0f,															// float									depthBiasSlopeFactor;
124 		1.0f															// float									lineWidth;
125 	};
126 
127 	const VkSubpassDescription						subpassDescription				=
128 	{
129 		(VkSubpassDescriptionFlags)0,		// VkSubpassDescriptionFlags		flags;
130 		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint
131 		0u,									// deUint32							inputAttachmentCount
132 		DE_NULL,							// const VkAttachmentReference*		pInputAttachments
133 		0u,									// deUint32							colorAttachmentCount
134 		DE_NULL,							// const VkAttachmentReference*		pColorAttachments
135 		DE_NULL,							// const VkAttachmentReference*		pResolveAttachments
136 		DE_NULL,							// const VkAttachmentReference*		pDepthStencilAttachment
137 		0u,									// deUint32							preserveAttachmentCount
138 		DE_NULL								// const deUint32*					pPreserveAttachments
139 	};
140 
141 	const VkRenderPassCreateInfo					renderPassCreateInfo			=
142 	{
143 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
144 		DE_NULL,										// const void*						pNext;
145 		(VkRenderPassCreateFlags)0,						// VkRenderPassCreateFlags			flags;
146 		0u,												// deUint32							attachmentCount
147 		DE_NULL,										// const VkAttachmentDescription*	pAttachments
148 		1u,												// deUint32							subpassCount
149 		&subpassDescription,							// const VkSubpassDescription*		pSubpasses
150 		0u,												// deUint32							dependencyCount
151 		DE_NULL											// const VkSubpassDependency*		pDependencies
152 	};
153 
154 	Unique<VkRenderPass>							renderPass						(createRenderPass(vk, device, &renderPassCreateInfo));
155 
156 	const VkGraphicsPipelineCreateInfo				graphicsPipelineCreateInfo		=
157 	{
158 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
159 		DE_NULL,											// const void*										pNext;
160 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
161 		1u,													// deUint32											stageCount;
162 		&shaderStageCreateInfo,								// const VkPipelineShaderStageCreateInfo*			pStages;
163 		&vertexInputStateCreateInfo,						// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
164 		&inputAssemblyStateCreateInfo,						// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
165 		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
166 		DE_NULL,											// const VkPipelineViewportStateCreateInfo*			pViewportState;
167 		&rasterizationStateCreateInfo,						// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
168 		DE_NULL,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
169 		DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
170 		DE_NULL,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
171 		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
172 		pipelineLayout.get(),								// VkPipelineLayout									layout;
173 		renderPass.get(),									// VkRenderPass										renderPass;
174 		0u,													// deUint32											subpass;
175 		DE_NULL,											// VkPipeline										basePipelineHandle;
176 		0													// int												basePipelineIndex;
177 	};
178 
179 	Unique<VkPipeline>								graphicsPipeline				(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
180 
181 	// Test should always pass
182 	return tcu::TestStatus::pass("Pass");
183 }
184 
descriptorSetLayoutLifetimeComputeTest(Context & context)185 tcu::TestStatus descriptorSetLayoutLifetimeComputeTest (Context& context)
186 {
187 	const DeviceInterface&					vk							= context.getDeviceInterface();
188 	const VkDevice							device						= context.getDevice();
189 
190 	Unique<VkPipelineLayout>				pipelineLayout				(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
191 
192 	const Unique<VkShaderModule>			computeShaderModule			(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
193 
194 	const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
195 	{
196 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
197 		DE_NULL,												// const void*						pNext;
198 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
199 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
200 		computeShaderModule.get(),								// VkShaderModule					shader;
201 		"main",													// const char*						pName;
202 		DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
203 	};
204 
205 	const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
206 	{
207 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType
208 		DE_NULL,											// const void*						pNext
209 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags			flags
210 		shaderStageCreateInfo,								// VkPipelineShaderStageCreateInfo	stage
211 		pipelineLayout.get(),								// VkPipelineLayout					layout
212 		DE_NULL,											// VkPipeline						basePipelineHandle
213 		0													// int								basePipelineIndex
214 	};
215 
216 	Unique<VkPipeline>						computePipeline				(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
217 
218 	// Test should always pass
219 	return tcu::TestStatus::pass("Pass");
220 }
221 
emptyDescriptorSetLayoutTest(Context & context,VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)222 tcu::TestStatus emptyDescriptorSetLayoutTest (Context& context, VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)
223 {
224 	const DeviceInterface&					vk								= context.getDeviceInterface();
225 	const VkDevice							device							= context.getDevice();
226 
227 	if (descriptorSetLayoutCreateFlags == VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
228 		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_push_descriptor"))
229 			TCU_THROW(NotSupportedError, "VK_KHR_push_descriptor extension not supported");
230 
231 	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
232 	{
233 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType                        sType;
234 		DE_NULL,												// const void*                            pNext;
235 		descriptorSetLayoutCreateFlags,							// VkDescriptorSetLayoutCreateFlags       flags;
236 		0u,														// deUint32                               bindingCount;
237 		DE_NULL													// const VkDescriptorSetLayoutBinding*    pBindings;
238 	};
239 
240 	Unique<VkDescriptorSetLayout>			descriptorSetLayout				(createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));
241 
242 	// Test should always pass
243 	return tcu::TestStatus::pass("Pass");
244 }
245 
246 } // anonymous
247 
createDescriptorSetLayoutLifetimeGraphicsSource(SourceCollections & dst)248 void createDescriptorSetLayoutLifetimeGraphicsSource (SourceCollections& dst)
249 {
250 	dst.glslSources.add("vertex") << glu::VertexSource(
251 		"#version 310 es\n"
252 		"void main (void)\n"
253 		"{\n"
254 		"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
255 		"}\n");
256 }
257 
createDescriptorSetLayoutLifetimeComputeSource(SourceCollections & dst)258 void createDescriptorSetLayoutLifetimeComputeSource (SourceCollections& dst)
259 {
260 	dst.glslSources.add("compute") << glu::ComputeSource(
261 		"#version 310 es\n"
262 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
263 		"void main (void)\n"
264 		"{\n"
265 		"}\n");
266 }
267 
createDescriptorSetLayoutLifetimeTests(tcu::TestContext & testCtx)268 tcu::TestCaseGroup* createDescriptorSetLayoutLifetimeTests (tcu::TestContext& testCtx)
269 {
270 	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_lifetime", "Descriptor set layout lifetime tests"));
271 
272 	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "graphics", "Test descriptor set layout lifetime in graphics pipeline", createDescriptorSetLayoutLifetimeGraphicsSource, descriptorSetLayoutLifetimeGraphicsTest);
273 	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "compute", "Test descriptor set layout lifetime in compute pipeline", createDescriptorSetLayoutLifetimeComputeSource,  descriptorSetLayoutLifetimeComputeTest);
274 
275 	return descriptorSetLayoutLifetimeTests.release();
276 }
277 
createEmptyDescriptorSetLayoutTests(tcu::TestContext & testCtx)278 tcu::TestCaseGroup* createEmptyDescriptorSetLayoutTests (tcu::TestContext& testCtx)
279 {
280 	de::MovePtr<tcu::TestCaseGroup> emptyDescriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "empty_set", "Create empty descriptor set layout tests"));
281 
282 	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "normal", "Create empty desciptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)0u);
283 	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "push_descriptor", "Create empty push descriptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
284 
285 	return emptyDescriptorSetLayoutTests.release();
286 }
287 
createDescriptorSetLayoutTests(tcu::TestContext & testCtx)288 tcu::TestCaseGroup* createDescriptorSetLayoutTests (tcu::TestContext& testCtx)
289 {
290 	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout", "Descriptor set layout tests"));
291 
292 	descriptorSetLayoutTests->addChild(createEmptyDescriptorSetLayoutTests(testCtx));
293 
294 	return descriptorSetLayoutTests.release();
295 }
296 
createDescriptorSetTests(tcu::TestContext & testCtx)297 tcu::TestCaseGroup* createDescriptorSetTests (tcu::TestContext& testCtx)
298 {
299 	de::MovePtr<tcu::TestCaseGroup> descriptorSetTests(new tcu::TestCaseGroup(testCtx, "descriptor_set", "Descriptor set tests"));
300 
301 	descriptorSetTests->addChild(createDescriptorSetLayoutLifetimeTests(testCtx));
302 	descriptorSetTests->addChild(createDescriptorSetLayoutTests(testCtx));
303 
304 	return descriptorSetTests.release();
305 }
306 
307 } // api
308 } // vkt
309