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 #include "vkCmdUtil.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vktApiBufferComputeInstance.hpp"
29 #include "vktApiComputeInstanceResultBuffer.hpp"
30 
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkPrograms.hpp"
34 
35 namespace vkt
36 {
37 namespace api
38 {
39 
40 namespace
41 {
42 
43 using namespace std;
44 using namespace vk;
45 
46 // Descriptor set layout used to create a pipeline layout is destroyed prior to creating a pipeline
createPipelineLayoutDestroyDescriptorSetLayout(const DeviceInterface & vk,const VkDevice & device)47 Move<VkPipelineLayout> createPipelineLayoutDestroyDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device)
48 {
49 	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutInfo		=
50 	{
51 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
52 		DE_NULL,												// const void*							pNext;
53 		(VkDescriptorSetLayoutCreateFlags)0,					// VkDescriptorSetLayoutCreateFlags		flags;
54 		0u,														// deUint32								bindingCount;
55 		DE_NULL,												// const VkDescriptorSetLayoutBinding*	pBindings;
56 	};
57 
58 	Unique<VkDescriptorSetLayout>			descriptorSetLayout			(createDescriptorSetLayout(vk, device, &descriptorSetLayoutInfo));
59 
60 	const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
61 	{
62 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType;
63 		DE_NULL,												// const void*						pNext;
64 		(VkPipelineLayoutCreateFlags)0,							// VkPipelineLayoutCreateFlags		flags;
65 		1u,														// deUint32							setLayoutCount;
66 		&descriptorSetLayout.get(),								// const VkDescriptorSetLayout*		pSetLayouts;
67 		0u,														// deUint32							pushConstantRangeCount;
68 		DE_NULL													// const VkPushConstantRange*		pPushConstantRanges;
69 	};
70 
71 	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
72 }
73 
descriptorSetLayoutLifetimeGraphicsTest(Context & context)74 tcu::TestStatus descriptorSetLayoutLifetimeGraphicsTest (Context& context)
75 {
76 	const DeviceInterface&							vk								= context.getDeviceInterface();
77 	const VkDevice									device							= context.getDevice();
78     deUint32					                    queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
79     const VkQueue					                queue				            = context.getUniversalQueue();
80 
81 	Unique<VkPipelineLayout>						pipelineLayout					(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
82 
83 	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
84 
85 	const VkPipelineShaderStageCreateInfo			shaderStageCreateInfo			=
86 	{
87 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
88 		DE_NULL,												// const void*						pNext;
89 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
90 		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits			stage;
91 		vertexShaderModule.get(),								// VkShaderModule					shader;
92 		"main",													// const char*						pName;
93 		DE_NULL,												// const VkSpecializationInfo*		pSpecializationInfo;
94 	};
95 
96 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
97 	{
98 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
99 		DE_NULL,													// const void*								pNext;
100 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags	flags;
101 		0u,															// deUint32									vertexBindingDescriptionCount;
102 		DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
103 		0u,															// deUint32									vertexAttributeDescriptionCount;
104 		DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
105 	};
106 
107 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
108 	{
109 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
110 		DE_NULL,														// const void*								pNext;
111 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
112 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology						topology;
113 		VK_FALSE														// VkBool32									primitiveRestartEnable;
114 	};
115 
116 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
117 	{
118 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
119 		DE_NULL,														// const void*								pNext;
120 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags	flags;
121 		VK_FALSE,														// VkBool32									depthClampEnable;
122 		VK_TRUE,														// VkBool32									rasterizerDiscardEnable;
123 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
124 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
125 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace								frontFace;
126 		VK_FALSE,														// VkBool32									depthBiasEnable;
127 		0.0f,															// float									depthBiasConstantFactor;
128 		0.0f,															// float									depthBiasClamp;
129 		0.0f,															// float									depthBiasSlopeFactor;
130 		1.0f															// float									lineWidth;
131 	};
132 
133 	const VkSubpassDescription						subpassDescription				=
134 	{
135 		(VkSubpassDescriptionFlags)0,		// VkSubpassDescriptionFlags		flags;
136 		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint
137 		0u,									// deUint32							inputAttachmentCount
138 		DE_NULL,							// const VkAttachmentReference*		pInputAttachments
139 		0u,									// deUint32							colorAttachmentCount
140 		DE_NULL,							// const VkAttachmentReference*		pColorAttachments
141 		DE_NULL,							// const VkAttachmentReference*		pResolveAttachments
142 		DE_NULL,							// const VkAttachmentReference*		pDepthStencilAttachment
143 		0u,									// deUint32							preserveAttachmentCount
144 		DE_NULL								// const deUint32*					pPreserveAttachments
145 	};
146 
147 	const VkRenderPassCreateInfo					renderPassCreateInfo			=
148 	{
149 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
150 		DE_NULL,										// const void*						pNext;
151 		(VkRenderPassCreateFlags)0,						// VkRenderPassCreateFlags			flags;
152 		0u,												// deUint32							attachmentCount
153 		DE_NULL,										// const VkAttachmentDescription*	pAttachments
154 		1u,												// deUint32							subpassCount
155 		&subpassDescription,							// const VkSubpassDescription*		pSubpasses
156 		0u,												// deUint32							dependencyCount
157 		DE_NULL											// const VkSubpassDependency*		pDependencies
158 	};
159 
160 	Unique<VkRenderPass>							renderPass						(createRenderPass(vk, device, &renderPassCreateInfo));
161 
162 	const VkGraphicsPipelineCreateInfo				graphicsPipelineCreateInfo		=
163 	{
164 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
165 		DE_NULL,											// const void*										pNext;
166 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
167 		1u,													// deUint32											stageCount;
168 		&shaderStageCreateInfo,								// const VkPipelineShaderStageCreateInfo*			pStages;
169 		&vertexInputStateCreateInfo,						// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
170 		&inputAssemblyStateCreateInfo,						// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
171 		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
172 		DE_NULL,											// const VkPipelineViewportStateCreateInfo*			pViewportState;
173 		&rasterizationStateCreateInfo,						// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
174 		DE_NULL,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
175 		DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
176 		DE_NULL,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
177 		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
178 		pipelineLayout.get(),								// VkPipelineLayout									layout;
179 		renderPass.get(),									// VkRenderPass										renderPass;
180 		0u,													// deUint32											subpass;
181 		DE_NULL,											// VkPipeline										basePipelineHandle;
182 		0													// int												basePipelineIndex;
183 	};
184 
185 	Unique<VkPipeline>								graphicsPipeline				(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
186 
187 
188 	VkFramebufferCreateInfo framebufferCreateInfo
189 	{
190 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType			sType
191 		DE_NULL,										// const void*				pNext
192 		0,												// VkFramebufferCreateFlags	flags
193 		*renderPass,									// VkRenderPass				renderPass
194 		0,												// uint32_t					attachmentCount
195 		DE_NULL,										// const VkImageView*		pAttachments
196 		16,												// uint32_t					width
197 		16,												// uint32_t					height
198 		1												// uint32_t					layers
199 	};
200 
201 	Move <VkFramebuffer> framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
202 
203 	const VkCommandPoolCreateInfo cmdPoolInfo			=
204 	{
205 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// Stype
206 		DE_NULL,										// PNext
207 		DE_NULL,										// flags
208 		queueFamilyIndex,								// queuefamilyindex
209 	};
210 
211 	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
212 
213 	const VkCommandBufferAllocateInfo		cmdBufParams =
214 	{
215 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	//	VkStructureType			sType;
216 		DE_NULL,										//	const void*				pNext;
217 		*cmdPool,										//	VkCommandPool			pool;
218 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				//	VkCommandBufferLevel	level;
219 		1u,												//	uint32_t				bufferCount;
220 	};
221 
222 	const Unique<VkCommandBuffer>			cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));
223 
224 	const VkRenderPassBeginInfo renderPassBeginInfo		=
225 	{
226 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
227 		DE_NULL,
228 		*renderPass,
229 		*framebuffer,
230 		{{0, 0}, {16, 16}},
231 		0,
232 		DE_NULL
233 	};
234 
235 	beginCommandBuffer(vk, *cmdBuf, 0u);
236 	{
237 		vk.cmdBeginRenderPass(*cmdBuf, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
238 		vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
239 		vk.cmdDraw(*cmdBuf, 3u, 1u, 0, 0);
240 		vk.cmdEndRenderPass(*cmdBuf);
241     }
242     endCommandBuffer(vk, *cmdBuf);
243 
244     submitCommandsAndWait(vk, device, queue, *cmdBuf);
245 
246 	// Test should always pass
247 	return tcu::TestStatus::pass("Pass");
248 }
249 
descriptorSetLayoutLifetimeComputeTest(Context & context)250 tcu::TestStatus descriptorSetLayoutLifetimeComputeTest (Context& context)
251 {
252 	const DeviceInterface&					vk							= context.getDeviceInterface();
253 	const VkDevice							device						= context.getDevice();
254     deUint32					            queueFamilyIndex            = context.getUniversalQueueFamilyIndex();
255     const VkQueue					        queue				        = context.getUniversalQueue();
256     Allocator&								allocator = context.getDefaultAllocator();
257     const ComputeInstanceResultBuffer		result(vk, device, allocator, 0.0f);
258 
259 
260     Unique<VkPipelineLayout>				pipelineLayout				(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
261 
262 	const Unique<VkShaderModule>			computeShaderModule			(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
263 
264 	const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
265 	{
266 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
267 		DE_NULL,												// const void*						pNext;
268 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
269 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
270 		computeShaderModule.get(),								// VkShaderModule					shader;
271 		"main",													// const char*						pName;
272 		DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
273 	};
274 
275 	const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
276 	{
277 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType
278 		DE_NULL,												// const void*						pNext
279 		(VkPipelineCreateFlags)0,								// VkPipelineCreateFlags			flags
280 		shaderStageCreateInfo,									// VkPipelineShaderStageCreateInfo	stage
281 		pipelineLayout.get(),									// VkPipelineLayout					layout
282 		DE_NULL,												// VkPipeline						basePipelineHandle
283 		0														// int								basePipelineIndex
284 	};
285 
286 	const deUint32							offset = (0u);
287 	const deUint32							addressableSize = 256;
288 	const deUint32							dataSize = 8;
289 	de::MovePtr<Allocation>					bufferMem;
290 	const Unique<VkBuffer>					buffer						(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
291 	const Unique<VkDescriptorSetLayout>		descriptorSetLayout			(createDescriptorSetLayout(context));
292 	const Unique<VkDescriptorPool>			descriptorPool				(createDescriptorPool(context));
293 	const Unique<VkDescriptorSet>			descriptorSet				(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
294 
295 	Unique<VkPipeline>						computePipeline				(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
296 
297 	const VkCommandPoolCreateInfo cmdPoolInfo				=
298 	{
299 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,				// Stype
300 		DE_NULL,												// PNext
301 		DE_NULL,												// flags
302 		queueFamilyIndex,										// queuefamilyindex
303 	};
304 
305 	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
306 
307 	const VkCommandBufferAllocateInfo		cmdBufParams	=
308 	{
309 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			//	VkStructureType			sType;
310 		DE_NULL,												//	const void*				pNext;
311 		*cmdPool,												//	VkCommandPool			pool;
312 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						//	VkCommandBufferLevel	level;
313 		1u,														//	uint32_t				bufferCount;
314 	};
315 
316 	const Unique<VkCommandBuffer>			cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));
317 
318 	beginCommandBuffer(vk, *cmdBuf, 0u);
319 	{
320 		vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
321 		vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &*descriptorSet, 0, 0);
322 		vk.cmdDispatch(*cmdBuf, 1u, 1u, 1u);
323 	}
324 	endCommandBuffer(vk, *cmdBuf);
325 
326 	submitCommandsAndWait(vk, device, queue, *cmdBuf);
327 
328 	// Test should always pass
329 	return tcu::TestStatus::pass("Pass");
330 }
331 
emptyDescriptorSetLayoutTest(Context & context,VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)332 tcu::TestStatus emptyDescriptorSetLayoutTest (Context& context, VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)
333 {
334 	const DeviceInterface&					vk								= context.getDeviceInterface();
335 	const VkDevice							device							= context.getDevice();
336 
337 	if (descriptorSetLayoutCreateFlags == VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
338 		if (!context.isDeviceFunctionalitySupported("VK_KHR_push_descriptor"))
339 			TCU_THROW(NotSupportedError, "VK_KHR_push_descriptor extension not supported");
340 
341 	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
342 	{
343 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType                        sType;
344 		DE_NULL,												// const void*                            pNext;
345 		descriptorSetLayoutCreateFlags,							// VkDescriptorSetLayoutCreateFlags       flags;
346 		0u,														// deUint32                               bindingCount;
347 		DE_NULL													// const VkDescriptorSetLayoutBinding*    pBindings;
348 	};
349 
350 	Unique<VkDescriptorSetLayout>			descriptorSetLayout				(createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));
351 
352 	// Test should always pass
353 	return tcu::TestStatus::pass("Pass");
354 }
355 
356 } // anonymous
357 
createDescriptorSetLayoutLifetimeGraphicsSource(SourceCollections & dst)358 void createDescriptorSetLayoutLifetimeGraphicsSource (SourceCollections& dst)
359 {
360 	dst.glslSources.add("vertex") << glu::VertexSource(
361 		"#version 310 es\n"
362 		"void main (void)\n"
363 		"{\n"
364 		"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
365 		"}\n");
366 }
367 
createDescriptorSetLayoutLifetimeComputeSource(SourceCollections & dst)368 void createDescriptorSetLayoutLifetimeComputeSource (SourceCollections& dst)
369 {
370 	dst.glslSources.add("compute") << glu::ComputeSource(
371 		"#version 310 es\n"
372 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
373 		"void main (void)\n"
374 		"{\n"
375 		"}\n");
376 }
377 
createDescriptorSetLayoutLifetimeTests(tcu::TestContext & testCtx)378 tcu::TestCaseGroup* createDescriptorSetLayoutLifetimeTests (tcu::TestContext& testCtx)
379 {
380 	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_lifetime", "Descriptor set layout lifetime tests"));
381 
382 	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "graphics", "Test descriptor set layout lifetime in graphics pipeline", createDescriptorSetLayoutLifetimeGraphicsSource, descriptorSetLayoutLifetimeGraphicsTest);
383 	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "compute", "Test descriptor set layout lifetime in compute pipeline", createDescriptorSetLayoutLifetimeComputeSource,  descriptorSetLayoutLifetimeComputeTest);
384 
385 	return descriptorSetLayoutLifetimeTests.release();
386 }
387 
createEmptyDescriptorSetLayoutTests(tcu::TestContext & testCtx)388 tcu::TestCaseGroup* createEmptyDescriptorSetLayoutTests (tcu::TestContext& testCtx)
389 {
390 	de::MovePtr<tcu::TestCaseGroup> emptyDescriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "empty_set", "Create empty descriptor set layout tests"));
391 
392 	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "normal", "Create empty desciptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)0u);
393 	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "push_descriptor", "Create empty push descriptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
394 
395 	return emptyDescriptorSetLayoutTests.release();
396 }
397 
createDescriptorSetLayoutTests(tcu::TestContext & testCtx)398 tcu::TestCaseGroup* createDescriptorSetLayoutTests (tcu::TestContext& testCtx)
399 {
400 	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout", "Descriptor set layout tests"));
401 
402 	descriptorSetLayoutTests->addChild(createEmptyDescriptorSetLayoutTests(testCtx));
403 
404 	return descriptorSetLayoutTests.release();
405 }
406 
createDescriptorSetTests(tcu::TestContext & testCtx)407 tcu::TestCaseGroup* createDescriptorSetTests (tcu::TestContext& testCtx)
408 {
409 	de::MovePtr<tcu::TestCaseGroup> descriptorSetTests(new tcu::TestCaseGroup(testCtx, "descriptor_set", "Descriptor set tests"));
410 
411 	descriptorSetTests->addChild(createDescriptorSetLayoutLifetimeTests(testCtx));
412 	descriptorSetTests->addChild(createDescriptorSetLayoutTests(testCtx));
413 
414 	return descriptorSetTests.release();
415 }
416 
417 } // api
418 } // vkt
419