• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiPipelineTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 
28 #include "deUniquePtr.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkBufferWithMemory.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "tcuTestLog.hpp"
41 
42 #include <vector>
43 #include <sstream>
44 
45 namespace vkt
46 {
47 namespace api
48 {
49 
50 namespace
51 {
52 
53 using namespace std;
54 using namespace vk;
55 
getRenderTargetFormat(const InstanceInterface & vk,const VkPhysicalDevice & device)56 VkFormat getRenderTargetFormat (const InstanceInterface& vk, const VkPhysicalDevice& device)
57 {
58 	const VkFormatFeatureFlags	featureFlags		= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
59 	VkFormatProperties			formatProperties;
60 
61 	vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties);
62 
63 	if ((formatProperties.linearTilingFeatures & featureFlags) || (formatProperties.optimalTilingFeatures & featureFlags))
64 		return VK_FORMAT_B8G8R8A8_UNORM;
65 
66 	vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties);
67 
68 	if ((formatProperties.linearTilingFeatures & featureFlags) || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
69 		return VK_FORMAT_R8G8B8A8_UNORM;
70 
71 	TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM");
72 
73 	return VK_FORMAT_UNDEFINED;
74 }
75 
createCommandBuffer(const DeviceInterface & vkd,VkDevice device,VkCommandPool commandPool)76 Move<VkCommandBuffer> createCommandBuffer (const DeviceInterface& vkd, VkDevice device, VkCommandPool commandPool)
77 {
78 	const VkCommandBufferAllocateInfo allocateInfo =
79 	{
80 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType         sType;
81 		DE_NULL,										// const void*             pNext;
82 		commandPool,									// VkCommandPool           commandPool;
83 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel    level;
84 		1u												// deUint32                commandBufferCount;
85 	};
86 
87 	return allocateCommandBuffer(vkd, device, &allocateInfo);
88 }
89 
90 enum DrawTriangleMode
91 {
92 	DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE = 0,
93 	DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE,
94 };
95 
drawTriangleTest(Context & context,DrawTriangleMode mode)96 tcu::TestStatus drawTriangleTest (Context& context, DrawTriangleMode mode)
97 {
98 	const DeviceInterface&							vk								= context.getDeviceInterface();
99 	const InstanceInterface&						vki								= context.getInstanceInterface();
100 	const VkDevice									device							= context.getDevice();
101 	const VkPhysicalDevice							physicalDevice					= context.getPhysicalDevice();
102 
103 	const VkFormat									format							= getRenderTargetFormat(vki, physicalDevice);
104 	const VkFormatProperties						formatProperties				(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
105 	const VkImageTiling								imageTiling						= (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR
106 																					: (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL
107 																					: VK_CORE_IMAGE_TILING_LAST;
108 
109 	const VkImageCreateInfo							attachmentImageCreateInfo		=
110 	{
111 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType          sType;
112 		DE_NULL,								// const void*              pNext;
113 		(VkImageCreateFlags)0u,					// VkImageCreateFlags       flags;
114 		VK_IMAGE_TYPE_2D,						// VkImageType              imageType;
115 		format,									// VkFormat                 format;
116 		{
117 			256u,	// deUint32    width;
118 			256u,	// deUint32    height;
119 			1u		// deUint32    depth;
120 		},										// VkExtent3D               extent;
121 		1u,										// deUint32                 mipLevels;
122 		1u,										// deUint32                 arrayLayers;
123 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits    samples;
124 		imageTiling,							// VkImageTiling            tiling;
125 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
126 		VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags        usage;
127 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode            sharingMode;
128 		0u,										// deUint32                 queueFamilyIndexCount;
129 		DE_NULL,								// const deUint32*          pQueueFamilyIndices;
130 		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout            initialLayout;
131 	};
132 
133 	const Unique<VkImage>							attachmentImage					(createImage(vk, device, &attachmentImageCreateInfo));
134 	de::MovePtr<Allocation>							attachmentImageMemory			= context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
135 
136 	VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset()));
137 
138 	const tcu::TextureFormat						resultFormat					= mapVkFormat(format);
139 	const VkDeviceSize								imageSizeBytes					= (VkDeviceSize)(resultFormat.getPixelSize() * 256 * 256);
140 	const VkBufferCreateInfo						readImageBufferParams
141 	{
142 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
143 		DE_NULL,									// const void*			pNext;
144 		0u,											// VkBufferCreateFlags	flags;
145 		imageSizeBytes,								// VkDeviceSize			size;
146 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
147 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
148 		0u,											// deUint32				queueFamilyCount;
149 		DE_NULL,									// const deUint32*		pQueueFamilyIndices;
150 	};
151 	const Unique<VkBuffer>				readImageBuffer(createBuffer(vk, device, &readImageBufferParams));
152 	const de::UniquePtr<Allocation>		readImageBufferMemory(context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));
153 
154 	VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
155 
156 	const deUint32									queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
157 
158 	const VkCommandPoolCreateInfo					commandPoolParams				=
159 	{
160 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType             sType;
161 		DE_NULL,										// const void*                 pNext;
162 		(VkCommandPoolCreateFlags)0u,					// VkCommandPoolCreateFlags    flags;
163 		queueFamilyIndex								// deUint32                    queueFamilyIndex;
164 	};
165 
166 	const Unique<VkCommandPool>						commandPool						(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
167 	const Unique<VkCommandBuffer>					commandBuffer					(createCommandBuffer(vk, device, commandPool.get()));
168 
169 	const VkCommandBufferBeginInfo					commandBufferBeginInfo			=
170 	{
171 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
172 		DE_NULL,										// const void*                              pNext;
173 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
174 		DE_NULL											// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
175 	};
176 
177 	VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
178 
179 	const VkAttachmentDescription					attachmentDescription			=
180 	{
181 		(VkAttachmentDescriptionFlags)0u,			// VkAttachmentDescriptionFlags    flags;
182 		format,										// VkFormat                        format;
183 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits           samples;
184 		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp              loadOp;
185 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp             storeOp;
186 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp              stencilLoadOp;
187 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp             stencilStoreOp;
188 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout                   initialLayout;
189 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout                   finalLayout;
190 	};
191 
192 	const VkAttachmentReference						attachmentReference				=
193 	{
194 		0u,											// deUint32			attachment;
195 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
196 	};
197 
198 	const VkSubpassDescription						subpassDescription				=
199 	{
200 		(VkSubpassDescriptionFlags)0u,		// VkSubpassDescriptionFlags       flags;
201 		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint             pipelineBindPoint
202 		0u,									// deUint32                        inputAttachmentCount
203 		DE_NULL,							// const VkAttachmentReference*    pInputAttachments
204 		1u,									// deUint32                        colorAttachmentCount
205 		&attachmentReference,				// const VkAttachmentReference*    pColorAttachments
206 		DE_NULL,							// const VkAttachmentReference*    pResolveAttachments
207 		DE_NULL,							// const VkAttachmentReference*    pDepthStencilAttachment
208 		0u,									// deUint32                        preserveAttachmentCount
209 		DE_NULL								// const deUint32*                 pPreserveAttachments
210 	};
211 
212 	const VkRenderPassCreateInfo					renderPassCreateInfo			=
213 	{
214 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType                   sType;
215 		DE_NULL,										// const void*                       pNext;
216 		(VkRenderPassCreateFlags)0u,					// VkRenderPassCreateFlags           flags;
217 		1u,												// deUint32                          attachmentCount
218 		&attachmentDescription,							// const VkAttachmentDescription*    pAttachments
219 		1u,												// deUint32                          subpassCount
220 		&subpassDescription,							// const VkSubpassDescription*       pSubpasses
221 		0u,												// deUint32                          dependencyCount
222 		DE_NULL											// const VkSubpassDependency*        pDependencies
223 	};
224 
225 	// When testing renderpass lifetime - create two compatible renderpasses, otherwise use just renderPassB
226 	VkRenderPass renderPassA;
227 	if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
228 		VK_CHECK(vk.createRenderPass(device, &renderPassCreateInfo, DE_NULL, &renderPassA));
229 
230 	const Move<VkRenderPass>						renderPassB						(createRenderPass(vk, device, &renderPassCreateInfo));
231 
232 	const VkImageViewCreateInfo						attachmentImageViewCreateInfo	=
233 	{
234 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType            sType;
235 		DE_NULL,										// const void*                pNext;
236 		(VkImageViewCreateFlags)0u,						// VkImageViewCreateFlags     flags;
237 		attachmentImage.get(),							// VkImage                    image;
238 		VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType            viewType;
239 		format,											// VkFormat                   format;
240 		{
241 			VK_COMPONENT_SWIZZLE_R,			// VkComponentSwizzle    r;
242 			VK_COMPONENT_SWIZZLE_G,			// VkComponentSwizzle    g;
243 			VK_COMPONENT_SWIZZLE_B,			// VkComponentSwizzle    b;
244 			VK_COMPONENT_SWIZZLE_A			// VkComponentSwizzle    a;
245 		},											// VkComponentMapping         components;
246 		{
247 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags    aspectMask;
248 			0u,								// deUint32              baseMipLevel;
249 			1u,								// deUint32              levelCount;
250 			0u,								// deUint32              baseArrayLayer;
251 			1u								// deUint32              layerCount;
252 		}											// VkImageSubresourceRange    subresourceRange;
253 	};
254 
255 	const Unique<VkImageView>						attachmentImageView				(createImageView(vk, device, &attachmentImageViewCreateInfo));
256 
257 	const VkFramebufferCreateInfo					framebufferCreateInfo			=
258 	{
259 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType             sType;
260 		DE_NULL,										// const void*                 pNext;
261 		(VkFramebufferCreateFlags)0u,					// VkFramebufferCreateFlags    flags;
262 		renderPassB.get(),								// VkRenderPass                renderPass;
263 		1u,												// deUint32                    attachmentCount;
264 		&attachmentImageView.get(),						// const VkImageView*          pAttachments;
265 		256u,											// deUint32                    width;
266 		256u,											// deUint32                    height;
267 		1u												// deUint32                    layers;
268 	};
269 
270 	const Unique<VkFramebuffer>						frameBuffer						(createFramebuffer(vk, device, &framebufferCreateInfo));
271 
272 	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
273 	const Unique<VkShaderModule>					fragmentShaderModule			(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
274 
275 	const VkPipelineLayoutCreateInfo				pipelineLayoutCreateInfo		=
276 	{
277 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType                     sType;
278 		DE_NULL,											// const void*                         pNext;
279 		(VkPipelineLayoutCreateFlags)0u,						// VkPipelineLayoutCreateFlags         flags;
280 		0u,													// deUint32                            setLayoutCount;
281 		DE_NULL,											// const VkDescriptorSetLayout*        pSetLayouts;
282 		0u,													// deUint32                            pushConstantRangeCount;
283 		DE_NULL												// const VkPushConstantRange*          pPushConstantRanges;
284 	};
285 
286 	Move<VkPipelineLayout>							pipelineLayout					(createPipelineLayout(vk, device, &pipelineLayoutCreateInfo));
287 
288 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
289 	{
290 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
291 		DE_NULL,														// const void*                                 pNext;
292 		(VkPipelineVertexInputStateCreateFlags)0u,						// VkPipelineVertexInputStateCreateFlags       flags;
293 		0u,																// deUint32                                    vertexBindingDescriptionCount;
294 		DE_NULL,														// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
295 		0u,																// deUint32                                    vertexAttributeDescriptionCount;
296 		DE_NULL															// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
297 	};
298 
299 	const VkViewport								viewport						=
300 	{
301 		0.0f,	// float    x;
302 		0.0f,	// float    y;
303 		64.0f,	// float    width;
304 		64.0f,	// float    height;
305 		0.0f,	// float    minDepth;
306 		0.0f,	// float    maxDepth;
307 	};
308 
309 	const std::vector<VkViewport>					viewports						(1, viewport);
310 	const std::vector<VkRect2D>						scissors						(1, makeRect2D(0, 0, 64u, 64u));
311 
312 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
313 	{
314 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                            sType;
315 		DE_NULL,														// const void*                                pNext;
316 		(VkPipelineRasterizationStateCreateFlags)0u,					// VkPipelineRasterizationStateCreateFlags    flags;
317 		VK_FALSE,														// VkBool32                                   depthClampEnable;
318 		VK_FALSE,														// VkBool32                                   rasterizerDiscardEnable;
319 		VK_POLYGON_MODE_FILL,											// VkPolygonMode                              polygonMode;
320 		VK_CULL_MODE_NONE,												// VkCullModeFlags                            cullMode;
321 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace                                frontFace;
322 		VK_FALSE,														// VkBool32                                   depthBiasEnable;
323 		0.0f,															// float                                      depthBiasConstantFactor;
324 		0.0f,															// float                                      depthBiasClamp;
325 		0.0f,															// float                                      depthBiasSlopeFactor;
326 		1.0f															// float                                      lineWidth;
327 	};
328 
329 	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState		=
330 	{
331 		VK_FALSE,						// VkBool32                 blendEnable;
332 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor            srcColorBlendFactor;
333 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor            dstColorBlendFactor;
334 		VK_BLEND_OP_ADD,				// VkBlendOp                colorBlendOp;
335 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor            srcAlphaBlendFactor;
336 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor            dstAlphaBlendFactor;
337 		VK_BLEND_OP_ADD,				// VkBlendOp                alphaBlendOp;
338 		(VkColorComponentFlags)0xF		// VkColorComponentFlags    colorWriteMask;
339 	};
340 
341 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateCreateInfo		=
342 	{
343 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType                               sType;
344 		DE_NULL,														// const void*                                   pNext;
345 		(VkPipelineColorBlendStateCreateFlags)0u,						// VkPipelineColorBlendStateCreateFlags          flags;
346 		VK_FALSE,														// VkBool32                                      logicOpEnable;
347 		VK_LOGIC_OP_CLEAR,												// VkLogicOp                                     logicOp;
348 		1u,																// deUint32                                      attachmentCount;
349 		&colorBlendAttachmentState,										// const VkPipelineColorBlendAttachmentState*    pAttachments;
350 		{ 1.0f, 1.0f, 1.0f, 1.0f }										// float                                         blendConstants[4];
351 	};
352 
353 	VkRenderPass renderPassUsedForPipeline = *renderPassB;
354 	if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
355 		renderPassUsedForPipeline = renderPassA;
356 
357 	const Unique<VkPipeline>						graphicsPipeline				(makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
358 																										  device,								// const VkDevice                                device
359 																										  *pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
360 																										  *vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
361 																										  DE_NULL,								// const VkShaderModule                          tessellationControlModule
362 																										  DE_NULL,								// const VkShaderModule                          tessellationEvalModule
363 																										  DE_NULL,								// const VkShaderModule                          geometryShaderModule
364 																										  *fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
365 																										  renderPassUsedForPipeline,			// const VkRenderPass                            renderPass
366 																										  viewports,							// const std::vector<VkViewport>&                viewports
367 																										  scissors,								// const std::vector<VkRect2D>&                  scissors
368 																										  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
369 																										  0u,									// const deUint32                                subpass
370 																										  0u,									// const deUint32                                patchControlPoints
371 																										  &vertexInputStateCreateInfo,			// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
372 																										  &rasterizationStateCreateInfo,		// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
373 																										  DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
374 																										  DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
375 																										  &colorBlendStateCreateInfo));			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
376 
377 	if (DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE == mode)
378 		pipelineLayout = decltype(pipelineLayout)();
379 
380 	beginRenderPass(vk, *commandBuffer, renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
381 
382 	vk.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
383 
384 	// Destroy the renderpass that was used to create the graphics pipeline
385 	if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
386 		vk.destroyRenderPass(device, renderPassA, DE_NULL);
387 
388 	vk.cmdDraw(*commandBuffer, 3u, 1u, 0u, 0u);
389 
390 	endRenderPass(vk, *commandBuffer);
391 
392 	// Copy image to buffer
393 	{
394 		copyImageToBuffer(vk, *commandBuffer, *attachmentImage, *readImageBuffer, tcu::IVec2(256, 256));
395 	}
396 
397 	VK_CHECK(vk.endCommandBuffer(*commandBuffer));
398 
399 	const VkSubmitInfo								submitInfo						=
400 	{
401 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
402 		DE_NULL,							// const void*                    pNext;
403 		0u,									// deUint32                       waitSemaphoreCount;
404 		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
405 		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
406 		1u,									// deUint32                       commandBufferCount;
407 		&commandBuffer.get(),				// const VkCommandBuffer*         pCommandBuffers;
408 		0u,									// deUint32                       signalSemaphoreCount;
409 		DE_NULL								// const VkSemaphore*             pSignalSemaphores;
410 	};
411 
412 	vk::VkQueue queue = context.getUniversalQueue();
413 
414 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
415 	VK_CHECK(vk.queueWaitIdle(queue));
416 	VK_CHECK(vk.deviceWaitIdle(device));
417 
418 	invalidateAlloc(vk, device, *readImageBufferMemory);
419 	const tcu::ConstPixelBufferAccess resultAccess(resultFormat, 256, 256, 1, readImageBufferMemory->getHostPtr());
420 
421 	// check just one pixel
422 	tcu::Vec4 pixel = resultAccess.getPixel(1, 1);
423 	if ((pixel.x() < 0.9f) || (pixel.y() > 0.1f) || (pixel.z() > 0.1f) || (pixel.w() < 0.9f))
424 		return tcu::TestStatus::fail("Fail");
425 
426 	tcu::TestLog& log = context.getTestContext().getLog();
427 	log << tcu::TestLog::ImageSet("Image verification", "")
428 		<< tcu::TestLog::Image("Result", "Result", resultAccess, tcu::Vec4(1.0f), tcu::Vec4(0.0f))
429 		<< tcu::TestLog::EndImageSet;
430 
431 	return tcu::TestStatus::pass("Pass");
432 }
433 
renderpassLifetimeTest(Context & context)434 tcu::TestStatus renderpassLifetimeTest(Context& context)
435 {
436 	return drawTriangleTest(context, DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE);
437 }
438 
createDrawTriangleSource(SourceCollections & dst)439 void createDrawTriangleSource (SourceCollections& dst)
440 {
441 	dst.glslSources.add("vertex") << glu::VertexSource(
442 		"#version 310 es\n"
443 		"void main (void)\n"
444 		"{\n"
445 		"    gl_Position = vec4(float(1 - 2 * int(gl_VertexIndex != 1)),\n"
446 		"                       float(1 - 2 * int(gl_VertexIndex > 0)), 0.0, 1.0);\n"
447 		"}\n");
448 
449 	dst.glslSources.add("fragment") << glu::FragmentSource(
450 		"#version 310 es\n"
451 		"layout (location = 0) out highp vec4 color;\n"
452 		"void main (void)\n"
453 		"{\n"
454 		"    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
455 		"}\n");
456 }
457 
changeColorAttachmentImageLayout(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkImage image)458 void changeColorAttachmentImageLayout (const DeviceInterface& vk, VkCommandBuffer commandBuffer, VkImage image)
459 {
460 	const VkImageMemoryBarrier		imageMemoryBarrier		=
461 	{
462 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType            sType;
463 		DE_NULL,									// const void*                pNext;
464 		(VkAccessFlags)0u,							// VkAccessFlags              srcAccessMask;
465 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags              dstAccessMask;
466 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout              oldLayout;
467 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout              newLayout;
468 		0u,											// deUint32                   srcQueueFamilyIndex;
469 		0u,											// deUint32                   dstQueueFamilyIndex;
470 		image,										// VkImage                    image;
471 		{
472 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags    aspectMask;
473 			0u,							// deUint32              baseMipLevel;
474 			1u,							// deUint32              levelCount;
475 			0u,							// deUint32              baseArrayLayer;(
476 			1u							// deUint32              layerCount;
477 		}											// VkImageSubresourceRange    subresourceRange;
478 	};
479 
480 	vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlagBits)0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier);
481 }
482 
createSimpleRenderPass(const DeviceInterface & vk,const VkDevice & device,VkFormat format,VkAttachmentLoadOp loadOp,VkAttachmentLoadOp stencilLoadOp,VkAttachmentStoreOp stencilStoreOp,VkImageLayout layout)483 Move<VkRenderPass> createSimpleRenderPass (const DeviceInterface& vk, const VkDevice& device, VkFormat format, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp, VkImageLayout layout)
484 {
485 	const VkAttachmentDescription	attachmentDescription	=
486 	{
487 		(VkAttachmentDescriptionFlags)0u,	// VkAttachmentDescriptionFlags    flags;
488 		format,								// VkFormat                        format;
489 		VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits           samples;
490 		loadOp,								// VkAttachmentLoadOp              loadOp;
491 		VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             storeOp;
492 		stencilLoadOp,						// VkAttachmentLoadOp              stencilLoadOp;
493 		stencilStoreOp,						// VkAttachmentStoreOp             stencilStoreOp;
494 		VK_IMAGE_LAYOUT_UNDEFINED,			// VkImageLayout                   initialLayout;
495 		layout								// VkImageLayout                   finalLayout;
496 	};
497 
498 	const VkAttachmentReference		attachmentReference		=
499 	{
500 		0u,		// deUint32			attachment;
501 		layout	// VkImageLayout	layout;
502 	};
503 
504 	const VkSubpassDescription		subpassDescription		=
505 	{
506 		(VkSubpassDescriptionFlags)0u,		// VkSubpassDescriptionFlags       flags;
507 		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint             pipelineBindPoint
508 		0u,									// deUint32                        inputAttachmentCount
509 		DE_NULL,							// const VkAttachmentReference*    pInputAttachments
510 		1u,									// deUint32                        colorAttachmentCount
511 		&attachmentReference,				// const VkAttachmentReference*    pColorAttachments
512 		DE_NULL,							// const VkAttachmentReference*    pResolveAttachments
513 		DE_NULL,							// const VkAttachmentReference*    pDepthStencilAttachment
514 		0u,									// deUint32                        preserveAttachmentCount
515 		DE_NULL								// const deUint32*                 pPreserveAttachments
516 	};
517 
518 	const VkRenderPassCreateInfo	renderPassCreateInfo	=
519 	{
520 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType                   sType;
521 		DE_NULL,									// const void*                       pNext;
522 		(VkRenderPassCreateFlags)0u,				// VkRenderPassCreateFlags           flags;
523 		1u,											// deUint32                          attachmentCount
524 		&attachmentDescription,						// const VkAttachmentDescription*    pAttachments
525 		1u,											// deUint32                          subpassCount
526 		&subpassDescription,						// const VkSubpassDescription*       pSubpasses
527 		0u,											// deUint32                          dependencyCount
528 		DE_NULL										// const VkSubpassDependency*        pDependencies
529 	};
530 
531 	return createRenderPass(vk, device, &renderPassCreateInfo);
532 }
533 
534 // This test has the same functionality as VkLayerTest.RenderPassInUseDestroyedSignaled
framebufferCompatibleRenderPassTest(Context & context)535 tcu::TestStatus framebufferCompatibleRenderPassTest (Context& context)
536 {
537 	const DeviceInterface&			vk						= context.getDeviceInterface();
538 	const InstanceInterface&		vki						= context.getInstanceInterface();
539 	const VkDevice					device					= context.getDevice();
540 	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();
541 	const VkQueue					queue					= context.getUniversalQueue();
542 	const deUint32					queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
543 
544 	const VkCommandPoolCreateInfo	commandPoolParams		=
545 	{
546 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// VkStructureType             sType;
547 		DE_NULL,									// const void*                 pNext;
548 		(VkCommandPoolCreateFlags)0u,				// VkCommandPoolCreateFlags    flags;
549 		queueFamilyIndex							// deUint32                    queueFamilyIndex;
550 	};
551 
552 	const Unique<VkCommandPool>		commandPool				(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
553 	const Unique<VkCommandBuffer>	commandBuffer			(createCommandBuffer(vk, device, commandPool.get()));
554 
555 	const VkCommandBufferBeginInfo	commandBufferBeginInfo	=
556 	{
557 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
558 		DE_NULL,										// const void*                              pNext;
559 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
560 		DE_NULL											// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
561 	};
562 
563 	VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
564 
565 	const VkFormat					format					= getRenderTargetFormat(vki, physicalDevice);
566 	const VkFormatProperties		formatProperties		(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
567 	const VkImageTiling				imageTiling				= (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR
568 															: (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL
569 															: VK_CORE_IMAGE_TILING_LAST;
570 
571 	const VkImageCreateInfo			imageCreateInfo			=
572 	{
573 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType          sType;
574 		DE_NULL,								// const void*              pNext;
575 		(VkImageCreateFlags)0u,					// VkImageCreateFlags       flags;
576 		VK_IMAGE_TYPE_2D,						// VkImageType              imageType;
577 		format,									// VkFormat                 format;
578 		{
579 			256u,	// deUint32    width;
580 			256u,	// deUint32    height;
581 			1u		// deUint32    depth;
582 		},										// VkExtent3D               extent;
583 		1u,										// deUint32                 mipLevels;
584 		1u,										// deUint32                 arrayLayers;
585 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits    samples;
586 		imageTiling,							// VkImageTiling            tiling;
587 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,	// VkImageUsageFlags        usage;
588 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode            sharingMode;
589 		0u,										// deUint32                 queueFamilyIndexCount;
590 		DE_NULL,								// const deUint32*          pQueueFamilyIndices;
591 		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout            initialLayout;
592 	};
593 
594 	const Unique<VkImage>			attachmentImage			(createImage(vk, device, &imageCreateInfo));
595 	de::MovePtr<Allocation>			attachmentImageMemory	= context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
596 
597 	VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset()));
598 
599 	changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
600 
601 	const VkImageViewCreateInfo		imageViewCreateInfo		=
602 	{
603 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType            sType;
604 		DE_NULL,									// const void*                pNext;
605 		(VkImageViewCreateFlags)0u,					// VkImageViewCreateFlags     flags;
606 		attachmentImage.get(),						// VkImage                    image;
607 		VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType            viewType;
608 		format,										// VkFormat                   format;
609 		{
610 			VK_COMPONENT_SWIZZLE_R,	// VkComponentSwizzle    r;
611 			VK_COMPONENT_SWIZZLE_G,	// VkComponentSwizzle    g;
612 			VK_COMPONENT_SWIZZLE_B,	// VkComponentSwizzle    b;
613 			VK_COMPONENT_SWIZZLE_A	// VkComponentSwizzle    a;
614 		},											// VkComponentMapping         components;
615 		{
616 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags    aspectMask;
617 			0u,							// deUint32              baseMipLevel;
618 			1u,							// deUint32              levelCount;
619 			0u,							// deUint32              baseArrayLayer;
620 			1u							// deUint32              layerCount;
621 		}											// VkImageSubresourceRange    subresourceRange;
622 	};
623 
624 	const Unique<VkImageView>		attachmentImageView		(createImageView(vk, device, &imageViewCreateInfo));
625 
626 	Unique<VkRenderPass>			renderPassA				(createSimpleRenderPass(vk, device, format,
627 																					VK_ATTACHMENT_LOAD_OP_CLEAR,
628 																					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
629 																					VK_ATTACHMENT_STORE_OP_DONT_CARE,
630 																					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
631 
632 	// Create framebuffer using the first render pass
633 	const VkFramebufferCreateInfo	framebufferCreateInfo	=
634 	{
635 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType             sType;
636 		DE_NULL,									// const void*                 pNext;
637 		(VkFramebufferCreateFlags)0u,				// VkFramebufferCreateFlags    flags;
638 		renderPassA.get(),							// VkRenderPass                renderPass;
639 		1u,											// deUint32                    attachmentCount;
640 		&attachmentImageView.get(),					// const VkImageView*          pAttachments;
641 		256u,										// deUint32                    width;
642 		256u,										// deUint32                    height;
643 		1u											// deUint32                    layers;
644 	};
645 
646 	const Unique<VkFramebuffer>		frameBuffer				(createFramebuffer(vk, device, &framebufferCreateInfo));
647 
648 	const Unique<VkRenderPass>		renderPassB				(createSimpleRenderPass(vk, device, format,
649 																					VK_ATTACHMENT_LOAD_OP_LOAD,
650 																					VK_ATTACHMENT_LOAD_OP_LOAD,
651 																					VK_ATTACHMENT_STORE_OP_STORE,
652 																					VK_IMAGE_LAYOUT_GENERAL));
653 
654 	beginRenderPass(vk, commandBuffer.get(), renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 0u, 0u));
655 	endRenderPass(vk, commandBuffer.get());
656 
657 	VK_CHECK(vk.endCommandBuffer(commandBuffer.get()));
658 
659 	const VkSubmitInfo				submitInfo				=
660 	{
661 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType                sType;
662 		DE_NULL,						// const void*                    pNext;
663 		0u,								// deUint32                       waitSemaphoreCount;
664 		DE_NULL,						// const VkSemaphore*             pWaitSemaphores;
665 		DE_NULL,						// const VkPipelineStageFlags*    pWaitDstStageMask;
666 		1u,								// deUint32                       commandBufferCount;
667 		&commandBuffer.get(),			// const VkCommandBuffer*         pCommandBuffers;
668 		0u,								// deUint32                       signalSemaphoreCount;
669 		DE_NULL							// const VkSemaphore*             pSignalSemaphores;
670 	};
671 
672 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
673 	VK_CHECK(vk.queueWaitIdle(queue));
674 
675 	// Test should always pass
676 	return tcu::TestStatus::pass("Pass");
677 }
678 
getDescriptorSetLayout(const DeviceInterface & vk,const VkDevice & device,deUint32 bindingCount,const VkDescriptorSetLayoutBinding * layoutBindings)679 Move<VkDescriptorSetLayout> getDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device, deUint32 bindingCount, const VkDescriptorSetLayoutBinding* layoutBindings)
680 {
681 	const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo =
682 	{
683 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType                        sType;
684 		DE_NULL,												// const void*                            pNext;
685 		(VkDescriptorSetLayoutCreateFlags)0u,					// VkDescriptorSetLayoutCreateFlags       flags;
686 		bindingCount,											// deUint32                               bindingCount;
687 		layoutBindings											// const VkDescriptorSetLayoutBinding*    pBindings;
688 	};
689 
690 	return createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo);
691 }
692 
getDescriptorSet(const DeviceInterface & vk,const VkDevice & device,VkDescriptorPool descriptorPool,VkDescriptorSetLayout setLayout)693 VkDescriptorSet getDescriptorSet (const DeviceInterface& vk, const VkDevice& device, VkDescriptorPool descriptorPool, VkDescriptorSetLayout setLayout)
694 {
695 	const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
696 	{
697 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                 sType;
698 		DE_NULL,										// const void*                     pNext;
699 		descriptorPool,									// VkDescriptorPool                descriptorPool;
700 		1u,												// deUint32                        descriptorSetCount;
701 		&setLayout										// const VkDescriptorSetLayout*    pSetLayouts;
702 	};
703 
704 	VkDescriptorSet descriptorSet;
705 	VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet));
706 
707 	return descriptorSet;
708 }
709 
getPipelineLayout(const DeviceInterface & vk,const VkDevice & device,deUint32 setLayoutCount,const VkDescriptorSetLayout * setLayouts)710 Move<VkPipelineLayout> getPipelineLayout (const DeviceInterface& vk, const VkDevice& device, deUint32 setLayoutCount, const VkDescriptorSetLayout* setLayouts)
711 {
712 	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
713 	{
714 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                 sType;
715 		DE_NULL,										// const void*                     pNext;
716 		(VkPipelineLayoutCreateFlags)0u,				// VkPipelineLayoutCreateFlags     flags;
717 		setLayoutCount,									// deUint32                        setLayoutCount;
718 		setLayouts,										// const VkDescriptorSetLayout*    pSetLayouts;
719 		0u,												// deUint32                        pushConstantRangeCount;
720 		DE_NULL											// const VkPushConstantRange*      pPushConstantRanges;
721 	};
722 
723 	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
724 }
725 
createSimpleGraphicsPipeline(const DeviceInterface & vk,const VkDevice & device,deUint32 numShaderStages,const VkPipelineShaderStageCreateInfo * shaderStageCreateInfos,VkPipelineLayout pipelineLayout,VkRenderPass renderPass)726 Move<VkPipeline> createSimpleGraphicsPipeline (const DeviceInterface& vk, const VkDevice& device, deUint32 numShaderStages, const VkPipelineShaderStageCreateInfo* shaderStageCreateInfos, VkPipelineLayout pipelineLayout, VkRenderPass renderPass)
727 {
728 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
729 	{
730 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
731 		DE_NULL,													// const void*                                 pNext;
732 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
733 		0u,															// deUint32                                    vertexBindingDescriptionCount;
734 		DE_NULL,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
735 		0u,															// deUint32                                    vertexAttributeDescriptionCount;
736 		DE_NULL														// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
737 	};
738 
739 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
740 	{
741 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                            sType;
742 		DE_NULL,														// const void*                                pNext;
743 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags    flags;
744 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology                        topology;
745 		VK_FALSE														// VkBool32                                   primitiveRestartEnable;
746 	};
747 
748 	const VkPipelineViewportStateCreateInfo			viewPortStateCreateInfo			=
749 	{
750 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                       sType;
751 		DE_NULL,												// const void*                           pNext;
752 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags    flags;
753 		1,														// deUint32                              viewportCount;
754 		DE_NULL,												// const VkViewport*                     pViewports;
755 		1,														// deUint32                              scissorCount;
756 		DE_NULL													// const VkRect2D*                       pScissors;
757 	};
758 
759 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
760 	{
761 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType                            sType;
762 		DE_NULL,													// const void*                                pNext;
763 		(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags    flags;
764 		VK_FALSE,													// VkBool32                                   depthClampEnable;
765 		VK_FALSE,													// VkBool32                                   rasterizerDiscardEnable;
766 		VK_POLYGON_MODE_FILL,										// VkPolygonMode                              polygonMode;
767 		VK_CULL_MODE_BACK_BIT,										// VkCullModeFlags                            cullMode;
768 		VK_FRONT_FACE_CLOCKWISE,									// VkFrontFace                                frontFace;
769 		VK_FALSE,													// VkBool32                                   depthBiasEnable;
770 		0.0f,														// float                                      depthBiasConstantFactor;
771 		0.0f,														// float                                      depthBiasClamp;
772 		0.0f,														// float                                      depthBiasSlopeFactor;
773 		1.0f														// float                                      lineWidth;
774 	};
775 
776 	const VkPipelineMultisampleStateCreateInfo		multisampleStateCreateInfo		=
777 	{
778 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType                          sType;
779 		DE_NULL,													// const void*                              pNext;
780 		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags    flags;
781 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits                    rasterizationSamples;
782 		VK_FALSE,													// VkBool32                                 sampleShadingEnable;
783 		0.0f,														// float                                    minSampleShading;
784 		DE_NULL,													// const VkSampleMask*                      pSampleMask;
785 		VK_FALSE,													// VkBool32                                 alphaToCoverageEnable;
786 		VK_FALSE													// VkBool32                                 alphaToOneEnable;
787 	};
788 
789 	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState		=
790 	{
791 		VK_FALSE,					// VkBool32                 blendEnable;
792 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            srcColorBlendFactor;
793 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            dstColorBlendFactor;
794 		VK_BLEND_OP_ADD,			// VkBlendOp                colorBlendOp;
795 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            srcAlphaBlendFactor;
796 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            dstAlphaBlendFactor;
797 		VK_BLEND_OP_ADD,			// VkBlendOp                alphaBlendOp;
798 		(VkColorComponentFlags)0xFu	// VkColorComponentFlags    colorWriteMask;
799 	};
800 
801 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateCreateInfo		=
802 	{
803 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType                               sType;
804 		DE_NULL,													// const void*                                   pNext;
805 		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags          flags;
806 		DE_FALSE,													// VkBool32                                      logicOpEnable;
807 		VK_LOGIC_OP_CLEAR,											// VkLogicOp                                     logicOp;
808 		1,															// deUint32                                      attachmentCount;
809 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*    pAttachments;
810 		{ 1.0f, 1.0f, 1.0f, 1.0f }									// float                                         blendConstants[4];
811 	};
812 
813 	const VkDynamicState							dynamicStates[]					=
814 	{
815 		VK_DYNAMIC_STATE_VIEWPORT,
816 		VK_DYNAMIC_STATE_SCISSOR
817 	};
818 
819 	const VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfo			=
820 	{
821 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType                      sType;
822 		DE_NULL,												// const void*                          pNext;
823 		(VkPipelineDynamicStateCreateFlags)0u,					// VkPipelineDynamicStateCreateFlags    flags;
824 		DE_LENGTH_OF_ARRAY(dynamicStates),						// deUint32                             dynamicStateCount;
825 		dynamicStates											// const VkDynamicState*                pDynamicStates;
826 	};
827 
828 	const VkGraphicsPipelineCreateInfo				graphicsPipelineCreateInfo		=
829 	{
830 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType                                  sType;
831 		DE_NULL,											// const void*                                      pNext;
832 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags                            flags;
833 		numShaderStages,									// deUint32                                         stageCount;
834 		shaderStageCreateInfos,								// const VkPipelineShaderStageCreateInfo*           pStages;
835 		&vertexInputStateCreateInfo,						// const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
836 		&inputAssemblyStateCreateInfo,						// const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
837 		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*     pTessellationState;
838 		&viewPortStateCreateInfo,							// const VkPipelineViewportStateCreateInfo*         pViewportState;
839 		&rasterizationStateCreateInfo,						// const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
840 		&multisampleStateCreateInfo,						// const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
841 		DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
842 		&colorBlendStateCreateInfo,							// const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
843 		&dynamicStateCreateInfo,							// const VkPipelineDynamicStateCreateInfo*          pDynamicState;
844 		pipelineLayout,										// VkPipelineLayout                                 layout;
845 		renderPass,											// VkRenderPass                                     renderPass;
846 		0u,													// deUint32                                         subpass;
847 		DE_NULL,											// VkPipeline                                       basePipelineHandle;
848 		0													// int                                              basePipelineIndex;
849 	};
850 
851 	const VkPipelineCacheCreateInfo					pipelineCacheCreateInfo			=
852 	{
853 		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType               sType;
854 		DE_NULL,										// const void*                   pNext;
855 		(VkPipelineCacheCreateFlags)0u,					// VkPipelineCacheCreateFlags    flags;
856 		0,												// size_t                        initialDataSize;
857 		DE_NULL											// const void*                   pInitialData;
858 	};
859 
860 	const Unique<VkPipelineCache>					pipelineCache					(createPipelineCache(vk, device, &pipelineCacheCreateInfo));
861 
862 	return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo);
863 }
864 
pipelineLayoutLifetimeTest(Context & context,VkPipelineBindPoint bindPoint)865 tcu::TestStatus pipelineLayoutLifetimeTest (Context& context, VkPipelineBindPoint bindPoint)
866 {
867 	const DeviceInterface&					vk							= context.getDeviceInterface();
868 	const InstanceInterface&				vki							= context.getInstanceInterface();
869 	const VkDevice							device						= context.getDevice();
870 	const VkPhysicalDevice					physicalDevice				= context.getPhysicalDevice();
871 	const deUint32							queueFamilyIndex			= context.getUniversalQueueFamilyIndex();
872 	const bool								isGraphics					= (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
873 
874 	const VkCommandPoolCreateInfo			commandPoolParams			=
875 	{
876 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// VkStructureType             sType;
877 		DE_NULL,									// const void*                 pNext;
878 		(VkCommandPoolCreateFlags)0u,				// VkCommandPoolCreateFlags    flags;
879 		queueFamilyIndex							// deUint32                    queueFamilyIndex;
880 	};
881 
882 	const Unique<VkCommandPool>				commandPool					(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
883 	const Unique<VkCommandBuffer>			commandBuffer				(createCommandBuffer(vk, device, commandPool.get()));
884 
885 	// Begin command buffer.
886 	{
887 		const VkCommandBufferBeginInfo commandBufferBeginInfo =
888 		{
889 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
890 			DE_NULL,										// const void*                              pNext;
891 			VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
892 			DE_NULL											// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
893 		};
894 
895 		VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
896 	}
897 
898 	// These will only be used for graphics pipelines.
899 	Move<VkImage>			attachmentImage;
900 	de::MovePtr<Allocation>	attachmentImageMemory;
901 	Move<VkImageView>		attachmentImageView;
902 	Move<VkRenderPass>		renderPass;
903 	Move<VkFramebuffer>		frameBuffer;
904 
905 	if (isGraphics)
906 	{
907 		// Create image, render pass and framebuffer.
908 		const VkFormat				format				= getRenderTargetFormat(vki, physicalDevice);
909 		const VkFormatProperties	formatProperties	(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
910 		const VkImageTiling			imageTiling			= (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR
911 														: (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL
912 														: VK_CORE_IMAGE_TILING_LAST;
913 
914 		const VkImageCreateInfo imageCreateInfo =
915 		{
916 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType          sType;
917 			DE_NULL,								// const void*              pNext;
918 			(VkImageCreateFlags)0u,					// VkImageCreateFlags       flags;
919 			VK_IMAGE_TYPE_2D,						// VkImageType              imageType;
920 			format,									// VkFormat                 format;
921 			{
922 				256u,	// deUint32    width;
923 				256u,	// deUint32    height;
924 				1u		// deUint32    depth;
925 			},										// VkExtent3D               extent;
926 			1u,										// deUint32                 mipLevels;
927 			1u,										// deUint32                 arrayLayers;
928 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits    samples;
929 			imageTiling,							// VkImageTiling            tiling;
930 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,	// VkImageUsageFlags        usage;
931 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode            sharingMode;
932 			0u,										// deUint32                 queueFamilyIndexCount;
933 			DE_NULL,								// const deUint32*          pQueueFamilyIndices;
934 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout            initialLayout;
935 		};
936 
937 		attachmentImage			= createImage(vk, device, &imageCreateInfo);
938 		attachmentImageMemory	= context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
939 
940 		VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset()));
941 
942 		changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
943 
944 		const VkImageViewCreateInfo imageViewCreateInfo =
945 		{
946 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType            sType;
947 			DE_NULL,									// const void*                pNext;
948 			(VkImageViewCreateFlags)0u,					// VkImageViewCreateFlags     flags;
949 			attachmentImage.get(),						// VkImage                    image;
950 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType            viewType;
951 			format,										// VkFormat                   format;
952 			{
953 				VK_COMPONENT_SWIZZLE_R,	// VkComponentSwizzle    r;
954 				VK_COMPONENT_SWIZZLE_G,	// VkComponentSwizzle    g;
955 				VK_COMPONENT_SWIZZLE_B,	// VkComponentSwizzle    b;
956 				VK_COMPONENT_SWIZZLE_A	// VkComponentSwizzle    a;
957 			},											// VkComponentMapping         components;
958 			{
959 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags    aspectMask;
960 				0u,							// deUint32              baseMipLevel;
961 				1u,							// deUint32              levelCount;
962 				0u,							// deUint32              baseArrayLayer;
963 				1u							// deUint32              layerCount;
964 			}											// VkImageSubresourceRange    subresourceRange;
965 		};
966 
967 		attachmentImageView	= createImageView(vk, device, &imageViewCreateInfo);
968 		renderPass			= createSimpleRenderPass(vk, device, format,
969 													 VK_ATTACHMENT_LOAD_OP_CLEAR,
970 													 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
971 													 VK_ATTACHMENT_STORE_OP_DONT_CARE,
972 													 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
973 
974 		const VkFramebufferCreateInfo framebufferCreateInfo =
975 		{
976 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType             sType;
977 			DE_NULL,										// const void*                 pNext;
978 			(VkFramebufferCreateFlags)0u,					// VkFramebufferCreateFlags    flags;
979 			renderPass.get(),								// VkRenderPass                renderPass;
980 			1u,												// deUint32                    attachmentCount;
981 			&attachmentImageView.get(),						// const VkImageView*          pAttachments;
982 			256u,											// deUint32                    width;
983 			256u,											// deUint32                    height;
984 			1u												// deUint32                    layers;
985 		};
986 
987 		frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
988 	}
989 
990 	const VkDescriptorPoolSize descriptorPoolSizes[] =
991 	{
992 		{
993 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	// VkDescriptorType    type;
994 			10									// deUint32            descriptorCount;
995 		},
996 		{
997 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType    type;
998 			2									// deUint32            descriptorCount;
999 		},
1000 		{
1001 			VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType    type;
1002 			2									// deUint32            descriptorCount;
1003 		}
1004 	};
1005 
1006 	VkDescriptorPool descriptorPool;
1007 	{
1008 		const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
1009 		{
1010 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,	// VkStructureType                sType;
1011 			DE_NULL,										// const void*                    pNext;
1012 			(VkDescriptorPoolCreateFlags)0u,				// VkDescriptorPoolCreateFlags    flags;
1013 			(isGraphics ? 3u : 5u),							// deUint32                       maxSets;
1014 			DE_LENGTH_OF_ARRAY(descriptorPoolSizes),		// deUint32                       poolSizeCount;
1015 			descriptorPoolSizes								// const VkDescriptorPoolSize*    pPoolSizes;
1016 		};
1017 
1018 		VK_CHECK(vk.createDescriptorPool(device, &descriptorPoolCreateInfo, DE_NULL, &descriptorPool));
1019 	}
1020 
1021 	const VkDescriptorSetLayoutBinding setLayoutBindingA[] =
1022 	{
1023 		{
1024 			0,									// deUint32              binding;
1025 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	// VkDescriptorType      descriptorType;
1026 			5,									// deUint32              descriptorCount;
1027 			VK_SHADER_STAGE_ALL,				// VkShaderStageFlags    stageFlags;
1028 			DE_NULL								// const VkSampler*      pImmutableSamplers;
1029 		}
1030 	};
1031 
1032 	const auto shaderStage = (isGraphics ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_COMPUTE_BIT);
1033 
1034 	const VkDescriptorSetLayoutBinding setLayoutBindingB[] =
1035 	{
1036 		{
1037 			0,									// deUint32              binding;
1038 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	// VkDescriptorType      descriptorType;
1039 			5,									// deUint32              descriptorCount;
1040 			(VkShaderStageFlags)shaderStage,	// VkShaderStageFlags    stageFlags;
1041 			DE_NULL								// const VkSampler*      pImmutableSamplers;
1042 		}
1043 	};
1044 
1045 	const VkDescriptorSetLayoutBinding setLayoutBindingC[] =
1046 	{
1047 		{
1048 			0,									// deUint32              binding;
1049 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType      descriptorType;
1050 			2,									// deUint32              descriptorCount;
1051 			VK_SHADER_STAGE_ALL,				// VkShaderStageFlags    stageFlags;
1052 			DE_NULL								// const VkSampler*      pImmutableSamplers;
1053 		},
1054 		{
1055 			1,									// deUint32              binding;
1056 			VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType      descriptorType;
1057 			2,									// deUint32              descriptorCount;
1058 			VK_SHADER_STAGE_ALL,				// VkShaderStageFlags    stageFlags;
1059 			DE_NULL								// const VkSampler*      pImmutableSamplers;
1060 		}
1061 	};
1062 
1063 	const Move<VkDescriptorSetLayout>		descriptorSetLayouts[]		=
1064 	{
1065 		getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingA), setLayoutBindingA),
1066 		getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingB), setLayoutBindingB),
1067 		getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingC), setLayoutBindingC)
1068 	};
1069 
1070 	const VkDescriptorSetLayout				setLayoutHandlesAC[]		=
1071 	{
1072 		descriptorSetLayouts[0].get(),
1073 		descriptorSetLayouts[2].get()
1074 	};
1075 
1076 	const VkDescriptorSetLayout				setLayoutHandlesB[]			=
1077 	{
1078 		descriptorSetLayouts[1].get()
1079 	};
1080 
1081 	const VkDescriptorSetLayout				setLayoutHandlesBC[]		=
1082 	{
1083 		descriptorSetLayouts[1].get(),
1084 		descriptorSetLayouts[2].get()
1085 	};
1086 
1087 	const VkDescriptorSet					descriptorSets[]			=
1088 	{
1089 		getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[0].get()),
1090 		getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[1].get()),
1091 		getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[2].get())
1092 	};
1093 
1094 	const VkDescriptorSet					setHandlesAC[]				=
1095 	{
1096 		descriptorSets[0],
1097 		descriptorSets[2]
1098 	};
1099 
1100 	const VkDescriptorSet					setHandlesC[]				=
1101 	{
1102 		descriptorSets[2]
1103 	};
1104 
1105 	const Unique<VkPipelineLayout>			pipelineLayoutAC			(getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesAC), setLayoutHandlesAC));
1106 	const Unique<VkPipelineLayout>			pipelineLayoutBC			(getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesBC), setLayoutHandlesBC));
1107 
1108 	VkPipelineLayout						pipelineLayoutB;
1109 	{
1110 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1111 		{
1112 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                 sType;
1113 			DE_NULL,										// const void*                     pNext;
1114 			(VkPipelineLayoutCreateFlags)0u,				// VkPipelineLayoutCreateFlags     flags;
1115 			DE_LENGTH_OF_ARRAY(setLayoutHandlesB),			// deUint32                        setLayoutCount;
1116 			setLayoutHandlesB,								// const VkDescriptorSetLayout*    pSetLayouts;
1117 			0u,												// deUint32                        pushConstantRangeCount;
1118 			DE_NULL											// const VkPushConstantRange*      pPushConstantRanges;
1119 		};
1120 
1121 		VK_CHECK(vk.createPipelineLayout(device, &pipelineLayoutCreateInfo, DE_NULL, &pipelineLayoutB));
1122 	}
1123 
1124 	std::vector<Move<VkShaderModule>>	shaderModules;
1125 	Move<VkPipeline>					pipeline;
1126 
1127 	if (isGraphics)
1128 	{
1129 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
1130 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
1131 
1132 		const VkPipelineShaderStageCreateInfo	shaderStageCreateInfos[]	=
1133 		{
1134 			{
1135 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1136 				DE_NULL,												// const void*                         pNext;
1137 				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1138 				VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits               stage;
1139 				shaderModules[0].get(),									// VkShaderModule                      shader;
1140 				"main",													// const char*                         pName;
1141 				DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1142 			},
1143 			{
1144 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1145 				DE_NULL,												// const void*                         pNext;
1146 				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1147 				VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits               stage;
1148 				shaderModules[1].get(),									// VkShaderModule                      shader;
1149 				"main",													// const char*                         pName;
1150 				DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1151 			}
1152 		};
1153 
1154 		pipeline = createSimpleGraphicsPipeline(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, pipelineLayoutB, renderPass.get());
1155 	}
1156 	else
1157 	{
1158 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
1159 
1160 		const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
1161 		{
1162 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1163 			DE_NULL,												// const void*                         pNext;
1164 			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1165 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits               stage;
1166 			shaderModules[0].get(),								// VkShaderModule                      shader;
1167 			"main",													// const char*                         pName;
1168 			DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1169 		};
1170 
1171 		const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
1172 		{
1173 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType                    sType;
1174 			DE_NULL,										// const void*                        pNext
1175 			(VkPipelineCreateFlags)0,						// VkPipelineCreateFlags              flags
1176 			shaderStageCreateInfo,							// VkPipelineShaderStageCreateInfo    stage
1177 			pipelineLayoutB,								// VkPipelineLayout                   layout
1178 			DE_NULL,										// VkPipeline                         basePipelineHandle
1179 			0												// int                                basePipelineIndex
1180 		};
1181 
1182 		pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo);
1183 	}
1184 
1185 	if (isGraphics)
1186 	{
1187 		beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
1188 	}
1189 	vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get());
1190 
1191 	// Destroy the pipeline layout that was used to create the pipeline
1192 	vk.destroyPipelineLayout(device, pipelineLayoutB, DE_NULL);
1193 
1194 	vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
1195 	vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutBC.get(), 1u, DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL);
1196 
1197 	if (isGraphics)
1198 	{
1199 		const VkViewport	viewport	=
1200 		{
1201 			0.0f,	// float    x;
1202 			0.0f,	// float    y;
1203 			16.0f,	// float    width;
1204 			16.0f,	// float    height;
1205 			0.0f,	// float    minDepth;
1206 			1.0f	// float    maxDepth;
1207 		};
1208 
1209 		const VkRect2D		scissor		=
1210 		{
1211 			{ 0u,	0u	},	// VkOffset2D    offset;
1212 			{ 16u,	16u	}	// VkExtent2D    extent;
1213 		};
1214 
1215 		vk.cmdSetViewport(commandBuffer.get(), 0u, 1u, &viewport);
1216 		vk.cmdSetScissor(commandBuffer.get(), 0u, 1u, &scissor);
1217 	}
1218 
1219 	vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
1220 
1221 	vk.destroyDescriptorPool(device, descriptorPool, DE_NULL);
1222 
1223 	// Test should always pass
1224 	return tcu::TestStatus::pass("Pass");
1225 }
1226 
createPipelineLayoutLifetimeGraphicsSource(SourceCollections & dst)1227 void createPipelineLayoutLifetimeGraphicsSource (SourceCollections& dst)
1228 {
1229 	dst.glslSources.add("vertex") << glu::VertexSource(
1230 		"#version 450\n"
1231 		"\n"
1232 		"void main (void)\n"
1233 		"{\n"
1234 		"   gl_Position = vec4(1);\n"
1235 		"}\n");
1236 
1237 	dst.glslSources.add("fragment") << glu::FragmentSource(
1238 		"#version 450\n"
1239 		"\n"
1240 		"layout(location=0) out vec4 x;\n"
1241 		"layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
1242 		"void main (void)\n"
1243 		"{\n"
1244 		"   x = vec4(bar.y);\n"
1245 		"}\n");
1246 }
1247 
1248 // This test has the same functionality as VkLayerTest.DescriptorSetCompatibility
pipelineLayoutLifetimeGraphicsTest(Context & context)1249 tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
1250 {
1251 	return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS);
1252 }
1253 
createPipelineLayoutLifetimeComputeSource(SourceCollections & dst)1254 void createPipelineLayoutLifetimeComputeSource (SourceCollections& dst)
1255 {
1256 	dst.glslSources.add("compute") << glu::ComputeSource(
1257 		"#version 450\n"
1258 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1259 		"layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
1260 		"void main (void)\n"
1261 		"{\n"
1262 		"    vec4 x = vec4(bar.y);\n"
1263 		"}\n");
1264 }
1265 
pipelineLayoutLifetimeComputeTest(Context & context)1266 tcu::TestStatus pipelineLayoutLifetimeComputeTest (Context& context)
1267 {
1268 	return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_COMPUTE);
1269 }
1270 
checkSupport(Context & context)1271 void checkSupport (Context& context)
1272 {
1273 	const InstanceInterface&	vki				= context.getInstanceInterface();
1274 	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
1275 
1276 	// Throws exception if not supported
1277 	getRenderTargetFormat(vki, physicalDevice);
1278 }
1279 
destroyEarlyComputeSource(SourceCollections & programs)1280 void destroyEarlyComputeSource(SourceCollections& programs)
1281 {
1282 	std::string comp =
1283 		"#version 450\n"
1284 		"layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1285 		"layout (constant_id=0) const uint flag = 0;\n"
1286 		"layout (push_constant, std430) uniform PushConstants {\n"
1287 		"    uint base;\n"
1288 		"};\n"
1289 		"layout (set=0, binding=0, std430) buffer Block {\n"
1290 		"    uint data[];\n"
1291 		"};\n"
1292 		"\n"
1293 		"void main() {\n"
1294 		"    if (flag != 0u) {\n"
1295 		"        uint idx = gl_GlobalInvocationID.x;\n"
1296 		"        data[idx] = data[idx] + base + idx;\n"
1297 		"    }\n"
1298 		"}\n";
1299 
1300 	programs.glslSources.add("comp") << glu::ComputeSource(comp);
1301 }
1302 
checkMaintenance4Support(Context & context)1303 void checkMaintenance4Support(Context& context)
1304 {
1305 	context.requireDeviceFunctionality("VK_KHR_maintenance4");
1306 }
1307 
1308 enum DestroyPipelineLayoutMode
1309 {
1310 	DPLM_DESTROY_AFTER_END_COMMAND_BUFFER = 0,
1311 	DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES,
1312 };
1313 
destroyEarlyTest(Context & context,DestroyPipelineLayoutMode mode)1314 tcu::TestStatus destroyEarlyTest (Context& context, DestroyPipelineLayoutMode mode)
1315 {
1316 	const auto&	vkd		= context.getDeviceInterface();
1317 	const auto	device	= context.getDevice();
1318 	auto&		alloc	= context.getDefaultAllocator();
1319 	const auto	queue	= context.getUniversalQueue();
1320 	const auto	qIndex	= context.getUniversalQueueFamilyIndex();
1321 
1322 	const deUint32	kBufferElements	= 100u;
1323 	const deUint32	kBufferSize		= kBufferElements * sizeof(deUint32);
1324 	const auto		kBufferSizeDS	= static_cast<VkDeviceSize>(kBufferSize);
1325 	const deUint32	kInitialValue	= 50u;
1326 	const deUint32	kFlagValue		= 1u;
1327 	const deUint32	kBaseValue		= 75u;
1328 
1329 	// Allocate and prepare buffer.
1330 	const auto				bufferInfo	= vk::makeBufferCreateInfo(kBufferSizeDS, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1331 	vk::BufferWithMemory	buffer		(vkd, device, alloc, bufferInfo, vk::MemoryRequirement::HostVisible);
1332 	auto&					bufferAlloc	= buffer.getAllocation();
1333 	void*					bufferPtr	= bufferAlloc.getHostPtr();
1334 	{
1335 		const std::vector<deUint32> bufferValues (kBufferElements, kInitialValue);
1336 		deMemcpy(bufferPtr, bufferValues.data(), kBufferSize);
1337 		vk::flushAlloc(vkd, device, bufferAlloc);
1338 	}
1339 
1340 	// Descriptor set layout.
1341 	vk::DescriptorSetLayoutBuilder layoutBuilder;
1342 	layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1343 	const auto descriptorSetLayout = layoutBuilder.build(vkd, device);
1344 
1345 	// Pipeline layout.
1346 	const auto pushConstantRange = vk::makePushConstantRange(vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast<deUint32>(sizeof(kBaseValue)));
1347 
1348 	const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo =
1349 	{
1350 		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
1351 		nullptr,											//	const void*						pNext;
1352 		0u,													//	VkPipelineLayoutCreateFlags		flags;
1353 		1u,													//	deUint32						setLayoutCount;
1354 		&descriptorSetLayout.get(),							//	const VkDescriptorSetLayout*	pSetLayouts;
1355 		1u,													//	deUint32						pushConstantRangeCount;
1356 		&pushConstantRange,									//	const VkPushConstantRange*		pPushConstantRanges;
1357 	};
1358 
1359 	auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
1360 
1361 	// Shader module.
1362 	const auto shaderModule = vk::createShaderModule(vkd, device, context.getBinaryCollection().get("comp"), 0u);
1363 
1364 	// Pipeline, with shader and specialization info.
1365 	const auto specConstantSize = static_cast<deUintptr>(sizeof(kFlagValue));
1366 
1367 	const vk::VkSpecializationMapEntry mapEntry =
1368 	{
1369 		0u,					//	deUint32	constantID;
1370 		0u,					//	deUint32	offset;
1371 		specConstantSize,	//	deUintptr	size;
1372 	};
1373 
1374 	const vk::VkSpecializationInfo specializationInfo =
1375 	{
1376 		1u,					//	deUint32						mapEntryCount;
1377 		&mapEntry,			//	const VkSpecializationMapEntry*	pMapEntries;
1378 		specConstantSize,	//	deUintptr						dataSize;
1379 		&kFlagValue,		//	const void*						pData;
1380 	};
1381 
1382 	const VkPipelineShaderStageCreateInfo shaderInfo =
1383 	{
1384 		vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
1385 		nullptr,													//	const void*							pNext;
1386 		0u,															//	VkPipelineShaderStageCreateFlags	flags;
1387 		vk::VK_SHADER_STAGE_COMPUTE_BIT,							//	VkShaderStageFlagBits				stage;
1388 		shaderModule.get(),											//	VkShaderModule						module;
1389 		"main",														//	const char*							pName;
1390 		&specializationInfo,										//	const VkSpecializationInfo*			pSpecializationInfo;
1391 	};
1392 	const vk::VkComputePipelineCreateInfo pipelineInfo =
1393 	{
1394 		vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			//	VkStructureType					sType;
1395 		nullptr,													//	const void*						pNext;
1396 		0u,															//	VkPipelineCreateFlags			flags;
1397 		shaderInfo,													//	VkPipelineShaderStageCreateInfo	stage;
1398 		pipelineLayout.get(),										//	VkPipelineLayout				layout;
1399 		DE_NULL,													//	VkPipeline						basePipelineHandle;
1400 		0,															//	deInt32							basePipelineIndex;
1401 	};
1402 
1403 	const auto pipeline = vk::createComputePipeline(vkd, device, DE_NULL, &pipelineInfo);
1404 
1405 	// Delete pipeline layout just after creating pipeline - this is what the test is for
1406 	if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode)
1407 		pipelineLayout = decltype(pipelineLayout)();
1408 
1409 	// Descriptor set.
1410 	vk::DescriptorPoolBuilder descriptorPoolBuilder;
1411 	descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1412 	const auto descriptorPool	= descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1413 	const auto descriptorSet	= vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1414 
1415 	// Update descriptor set with buffer.
1416 	vk::DescriptorSetUpdateBuilder updateBuilder;
1417 	const auto descriptorInfo = vk::makeDescriptorBufferInfo(buffer.get(), static_cast<VkDeviceSize>(0), kBufferSizeDS);
1418 	updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo);
1419 	updateBuilder.update(vkd, device);
1420 
1421 	// Prepare command buffer.
1422 	const auto cmdPool		= vk::makeCommandPool(vkd, device, qIndex);
1423 	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1424 	const auto cmdBuffer	= cmdBufferPtr.get();
1425 	const auto barrier		= vk::makeMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT);
1426 
1427 	// Create new pipeline layout that will be used during dispatch
1428 	if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode)
1429 		pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
1430 
1431 	vk::beginCommandBuffer(vkd, cmdBuffer);
1432 	vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get());
1433 	vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
1434 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast<deUint32>(sizeof(kBaseValue)), &kBaseValue);
1435 	vkd.cmdDispatch(cmdBuffer, kBufferElements, 1u, 1u);
1436 	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
1437 	vk::endCommandBuffer(vkd, cmdBuffer);
1438 
1439 	// Delete pipeline layout just after recording command buffer - this is what the test is for
1440 	if (DPLM_DESTROY_AFTER_END_COMMAND_BUFFER == mode)
1441 		pipelineLayout = decltype(pipelineLayout)();
1442 
1443 	// Submit commands.
1444 	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1445 
1446 	// Check buffer.
1447 	vk::invalidateAlloc(vkd, device, bufferAlloc);
1448 	std::vector<deUint32> outputData (kBufferElements);
1449 	deMemcpy(outputData.data(), bufferPtr, kBufferSize);
1450 
1451 	for (deUint32 i = 0; i < kBufferElements; ++i)
1452 	{
1453 		// This matches what the shader should calculate.
1454 		const auto expectedValue = kInitialValue + kBaseValue + i;
1455 		if (outputData[i] != expectedValue)
1456 		{
1457 			std::ostringstream msg;
1458 			msg << "Unexpected value at buffer position " << i << ": expected " << expectedValue << " but found " << outputData[i];
1459 			return tcu::TestStatus::fail(msg.str());
1460 		}
1461 	}
1462 
1463 	return tcu::TestStatus::pass("Pass");
1464 }
1465 
destroyAfterEndCommndBufferTest(Context & context)1466 tcu::TestStatus destroyAfterEndCommndBufferTest(Context& context)
1467 {
1468 	return destroyEarlyTest(context, DPLM_DESTROY_AFTER_END_COMMAND_BUFFER);
1469 }
1470 
destroyAfterCreateComputePipelineTest(Context & context)1471 tcu::TestStatus destroyAfterCreateComputePipelineTest(Context& context)
1472 {
1473 	return destroyEarlyTest(context, DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES);
1474 }
1475 
destroyAfterCreateGraphicsPipelineTest(Context & context)1476 tcu::TestStatus destroyAfterCreateGraphicsPipelineTest(Context& context)
1477 {
1478 	return drawTriangleTest(context, DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE);
1479 }
1480 
createSimpleGraphicsPipelineInvalidPointers(const DeviceInterface & vk,const VkDevice & device,deUint32 numShaderStages,const VkPipelineShaderStageCreateInfo * shaderStageCreateInfos,VkPipelineLayout pipelineLayout,VkRenderPass renderPass)1481 Move<VkPipeline> createSimpleGraphicsPipelineInvalidPointers (const DeviceInterface& vk, const VkDevice& device, deUint32 numShaderStages, const VkPipelineShaderStageCreateInfo* shaderStageCreateInfos, VkPipelineLayout pipelineLayout, VkRenderPass renderPass)
1482 {
1483 	const void *invalidPointer = reinterpret_cast<void*>(~(0));
1484 
1485 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
1486 	{
1487 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
1488 		DE_NULL,													// const void*                                 pNext;
1489 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
1490 		0u,															// deUint32                                    vertexBindingDescriptionCount;
1491 		DE_NULL,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
1492 		0u,															// deUint32                                    vertexAttributeDescriptionCount;
1493 		(const VkVertexInputAttributeDescription*)invalidPointer	// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
1494 	};
1495 
1496 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
1497 	{
1498 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                            sType;
1499 		DE_NULL,														// const void*                                pNext;
1500 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags    flags;
1501 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology                        topology;
1502 		VK_FALSE														// VkBool32                                   primitiveRestartEnable;
1503 	};
1504 
1505 	// Disable rasterization to test unused structs
1506 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
1507 	{
1508 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType                            sType;
1509 		DE_NULL,													// const void*                                pNext;
1510 		(VkPipelineRasterizationStateCreateFlags)0,					// VkPipelineRasterizationStateCreateFlags    flags;
1511 		VK_FALSE,													// VkBool32                                   depthClampEnable;
1512 		VK_TRUE,													// VkBool32                                   rasterizerDiscardEnable;
1513 		VK_POLYGON_MODE_FILL,										// VkPolygonMode                              polygonMode;
1514 		VK_CULL_MODE_BACK_BIT,										// VkCullModeFlags                            cullMode;
1515 		VK_FRONT_FACE_CLOCKWISE,									// VkFrontFace                                frontFace;
1516 		VK_FALSE,													// VkBool32                                   depthBiasEnable;
1517 		0.0f,														// float                                      depthBiasConstantFactor;
1518 		0.0f,														// float                                      depthBiasClamp;
1519 		0.0f,														// float                                      depthBiasSlopeFactor;
1520 		1.0f														// float                                      lineWidth;
1521 	};
1522 
1523 	const VkGraphicsPipelineCreateInfo				graphicsPipelineCreateInfo		=
1524 	{
1525 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType                                  sType;
1526 		DE_NULL,														// const void*                                      pNext;
1527 		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags                            flags;
1528 		numShaderStages,												// deUint32                                         stageCount;
1529 		shaderStageCreateInfos,											// const VkPipelineShaderStageCreateInfo*           pStages;
1530 		&vertexInputStateCreateInfo,									// const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
1531 		&inputAssemblyStateCreateInfo,									// const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
1532 		DE_NULL,														// const VkPipelineTessellationStateCreateInfo*     pTessellationState;
1533 		(const VkPipelineViewportStateCreateInfo*)invalidPointer,		// const VkPipelineViewportStateCreateInfo*         pViewportState;
1534 		&rasterizationStateCreateInfo,									// const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
1535 		(const VkPipelineMultisampleStateCreateInfo*)invalidPointer,	// const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
1536 		(const VkPipelineDepthStencilStateCreateInfo*)invalidPointer,	// const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
1537 		(const VkPipelineColorBlendStateCreateInfo*)invalidPointer,		// const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
1538 		DE_NULL,														// const VkPipelineDynamicStateCreateInfo*          pDynamicState;
1539 		pipelineLayout,													// VkPipelineLayout                                 layout;
1540 		renderPass,														// VkRenderPass                                     renderPass;
1541 		0u,																// deUint32                                         subpass;
1542 		DE_NULL,														// VkPipeline                                       basePipelineHandle;
1543 		0																// int                                              basePipelineIndex;
1544 	};
1545 
1546 	const VkPipelineCacheCreateInfo					pipelineCacheCreateInfo			=
1547 	{
1548 		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType               sType;
1549 		DE_NULL,										// const void*                   pNext;
1550 		(VkPipelineCacheCreateFlags)0u,					// VkPipelineCacheCreateFlags    flags;
1551 		0,												// size_t                        initialDataSize;
1552 		invalidPointer									// const void*                   pInitialData;
1553 	};
1554 
1555 	const Unique<VkPipelineCache>					pipelineCache					(createPipelineCache(vk, device, &pipelineCacheCreateInfo));
1556 
1557 	return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo);
1558 }
1559 
pipelineInvalidPointersUnusedStructsTest(Context & context,VkPipelineBindPoint bindPoint)1560 tcu::TestStatus pipelineInvalidPointersUnusedStructsTest (Context& context, VkPipelineBindPoint bindPoint)
1561 {
1562 	const DeviceInterface&					vk							= context.getDeviceInterface();
1563 	const VkDevice							device						= context.getDevice();
1564 	const VkQueue							queue						= context.getUniversalQueue();
1565 	const deUint32							queueFamilyIndex			= context.getUniversalQueueFamilyIndex();
1566 	const bool								isGraphics					= (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
1567 	const void								*invalidPointer				= reinterpret_cast<void*>(~(0));
1568 
1569 	const VkCommandPoolCreateInfo			commandPoolParams			=
1570 	{
1571 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// VkStructureType             sType;
1572 		DE_NULL,									// const void*                 pNext;
1573 		(VkCommandPoolCreateFlags)0u,				// VkCommandPoolCreateFlags    flags;
1574 		queueFamilyIndex							// deUint32                    queueFamilyIndex;
1575 	};
1576 
1577 	const Unique<VkCommandPool>				commandPool					(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
1578 	const Unique<VkCommandBuffer>			commandBuffer				(createCommandBuffer(vk, device, commandPool.get()));
1579 
1580 	// Begin command buffer.
1581 	{
1582 		const VkCommandBufferBeginInfo commandBufferBeginInfo =
1583 		{
1584 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
1585 			DE_NULL,										// const void*                              pNext;
1586 			VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
1587 			DE_NULL											// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
1588 		};
1589 
1590 		VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
1591 	}
1592 
1593 	// These will only be used for graphics pipelines.
1594 	Move<VkRenderPass>		renderPass;
1595 	Move<VkFramebuffer>		frameBuffer;
1596 
1597 	{
1598 		const VkSubpassDescription		subpassDescription		=
1599 		{
1600 			(VkSubpassDescriptionFlags)0u,						// VkSubpassDescriptionFlags       flags;
1601 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint             pipelineBindPoint
1602 			0u,													// deUint32                        inputAttachmentCount
1603 			(const VkAttachmentReference*)invalidPointer,		// const VkAttachmentReference*    pInputAttachments
1604 			0u,													// deUint32                        colorAttachmentCount
1605 			(const VkAttachmentReference*)invalidPointer,		// const VkAttachmentReference*    pColorAttachments
1606 			DE_NULL,											// const VkAttachmentReference*    pResolveAttachments
1607 			DE_NULL,											// const VkAttachmentReference*    pDepthStencilAttachment
1608 			0u,													// deUint32                        preserveAttachmentCount
1609 			(const deUint32*)invalidPointer						// const deUint32*                 pPreserveAttachments
1610 		};
1611 
1612 		const VkRenderPassCreateInfo	renderPassCreateInfo	=
1613 		{
1614 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType                   sType;
1615 			DE_NULL,											// const void*                       pNext;
1616 			(VkRenderPassCreateFlags)0u,						// VkRenderPassCreateFlags           flags;
1617 			0u,													// deUint32                          attachmentCount
1618 			(const VkAttachmentDescription*)invalidPointer,		// const VkAttachmentDescription*    pAttachments
1619 			1u,													// deUint32                          subpassCount
1620 			&subpassDescription,								// const VkSubpassDescription*       pSubpasses
1621 			0u,													// deUint32                          dependencyCount
1622 			(const VkSubpassDependency*)invalidPointer			// const VkSubpassDependency*        pDependencies
1623 		};
1624 		renderPass			= createRenderPass(vk, device, &renderPassCreateInfo);
1625 
1626 		const VkFramebufferCreateInfo framebufferCreateInfo =
1627 		{
1628 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType             sType;
1629 			DE_NULL,										// const void*                 pNext;
1630 			(VkFramebufferCreateFlags)0u,					// VkFramebufferCreateFlags    flags;
1631 			renderPass.get(),								// VkRenderPass                renderPass;
1632 			0u,												// deUint32                    attachmentCount;
1633 			(const VkImageView*)invalidPointer,				// const VkImageView*          pAttachments;
1634 			256u,											// deUint32                    width;
1635 			256u,											// deUint32                    height;
1636 			1u												// deUint32                    layers;
1637 		};
1638 
1639 		frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
1640 	}
1641 
1642 	Move<VkPipelineLayout>				pipelineLayout;
1643 	{
1644 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1645 		{
1646 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                 sType;
1647 			DE_NULL,										// const void*                     pNext;
1648 			(VkPipelineLayoutCreateFlags)0u,				// VkPipelineLayoutCreateFlags     flags;
1649 			0u,												// deUint32                        setLayoutCount;
1650 			(const VkDescriptorSetLayout*)invalidPointer,	// const VkDescriptorSetLayout*    pSetLayouts;
1651 			0u,												// deUint32                        pushConstantRangeCount;
1652 			(const VkPushConstantRange*)invalidPointer		// const VkPushConstantRange*      pPushConstantRanges;
1653 		};
1654 
1655 		pipelineLayout = vk::createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
1656 	}
1657 
1658 	std::vector<Move<VkShaderModule>>	shaderModules;
1659 	Move<VkPipeline>					pipeline;
1660 
1661 	if (isGraphics)
1662 	{
1663 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
1664 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
1665 
1666 		const VkPipelineShaderStageCreateInfo	shaderStageCreateInfos[]	=
1667 		{
1668 			{
1669 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1670 				DE_NULL,												// const void*                         pNext;
1671 				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1672 				VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits               stage;
1673 				shaderModules[0].get(),									// VkShaderModule                      shader;
1674 				"main",													// const char*                         pName;
1675 				DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1676 			},
1677 			{
1678 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1679 				DE_NULL,												// const void*                         pNext;
1680 				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1681 				VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits               stage;
1682 				shaderModules[1].get(),									// VkShaderModule                      shader;
1683 				"main",													// const char*                         pName;
1684 				DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1685 			}
1686 		};
1687 
1688 		pipeline = createSimpleGraphicsPipelineInvalidPointers(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, *pipelineLayout, renderPass.get());
1689 	}
1690 	else
1691 	{
1692 		shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
1693 
1694 		const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
1695 		{
1696 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
1697 			DE_NULL,												// const void*                         pNext;
1698 			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags    flags;
1699 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits               stage;
1700 			shaderModules[0].get(),									// VkShaderModule                      shader;
1701 			"main",													// const char*                         pName;
1702 			DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
1703 		};
1704 
1705 		const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
1706 		{
1707 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType                    sType;
1708 			DE_NULL,										// const void*                        pNext
1709 			(VkPipelineCreateFlags)0,						// VkPipelineCreateFlags              flags
1710 			shaderStageCreateInfo,							// VkPipelineShaderStageCreateInfo    stage
1711 			*pipelineLayout,									// VkPipelineLayout                   layout
1712 			DE_NULL,										// VkPipeline                         basePipelineHandle
1713 			0												// int                                basePipelineIndex
1714 		};
1715 
1716 		pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo);
1717 	}
1718 
1719 	if (isGraphics)
1720 	{
1721 		beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
1722 	}
1723 	vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get());
1724 
1725 	if (isGraphics)
1726 	{
1727 		vk.cmdDraw(commandBuffer.get(), 1u, 1u, 0u, 0u);
1728 		vk.cmdEndRenderPass(commandBuffer.get());
1729 	}
1730 	else
1731 	{
1732 		vk.cmdDispatch(commandBuffer.get(), 1u, 1u, 1u);
1733 	}
1734 	vk.endCommandBuffer(commandBuffer.get());
1735 
1736 	const VkSubmitInfo				submitInfo				=
1737 	{
1738 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType                sType;
1739 		DE_NULL,						// const void*                    pNext;
1740 		0u,								// deUint32                       waitSemaphoreCount;
1741 		DE_NULL,						// const VkSemaphore*             pWaitSemaphores;
1742 		DE_NULL,						// const VkPipelineStageFlags*    pWaitDstStageMask;
1743 		1u,								// deUint32                       commandBufferCount;
1744 		&commandBuffer.get(),			// const VkCommandBuffer*         pCommandBuffers;
1745 		0u,								// deUint32                       signalSemaphoreCount;
1746 		DE_NULL							// const VkSemaphore*             pSignalSemaphores;
1747 	};
1748 
1749 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
1750 	VK_CHECK(vk.queueWaitIdle(queue));
1751 
1752 	// Test should always pass
1753 	return tcu::TestStatus::pass("Pass");
1754 }
1755 
createPipelineInvalidPointersUnusedStructsGraphicsSource(SourceCollections & dst)1756 void createPipelineInvalidPointersUnusedStructsGraphicsSource (SourceCollections& dst)
1757 {
1758 	dst.glslSources.add("vertex") << glu::VertexSource(
1759 		"#version 450\n"
1760 		"\n"
1761 		"void main (void)\n"
1762 		"{\n"
1763 		"   gl_Position = vec4(1.0f);\n"
1764 		"}\n");
1765 
1766 	dst.glslSources.add("fragment") << glu::FragmentSource(
1767 		"#version 450\n"
1768 		"\n"
1769 		"void main (void)\n"
1770 		"{\n"
1771 		"}\n");
1772 }
1773 
pipelineInvalidPointersUnusedStructsGraphicsTest(Context & context)1774 tcu::TestStatus pipelineInvalidPointersUnusedStructsGraphicsTest (Context& context)
1775 {
1776 	return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS);
1777 }
1778 
createPipelineInvalidPointersUnusedStructsComputeSource(SourceCollections & dst)1779 void createPipelineInvalidPointersUnusedStructsComputeSource (SourceCollections& dst)
1780 {
1781 	dst.glslSources.add("compute") << glu::ComputeSource(
1782 		"#version 450\n"
1783 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1784 		"void main (void)\n"
1785 		"{\n"
1786 		"}\n");
1787 }
1788 
pipelineInvalidPointersUnusedStructsComputeTest(Context & context)1789 tcu::TestStatus pipelineInvalidPointersUnusedStructsComputeTest (Context& context)
1790 {
1791 	return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_COMPUTE);
1792 }
1793 
createrenderpassTests(tcu::TestContext & testCtx)1794 tcu::TestCaseGroup* createrenderpassTests (tcu::TestContext& testCtx)
1795 {
1796 	de::MovePtr<tcu::TestCaseGroup> renderPassTests(new tcu::TestCaseGroup(testCtx, "renderpass", "Renderpass tests"));
1797 
1798 	addFunctionCaseWithPrograms(renderPassTests.get(), "destroy_pipeline_renderpass", "Draw after destroying the renderpass used to create a pipeline", checkSupport, createDrawTriangleSource, renderpassLifetimeTest);
1799 	addFunctionCase(renderPassTests.get(), "framebuffer_compatible_renderpass", "Use a render pass with a framebuffer that was created using another compatible render pass", checkSupport, framebufferCompatibleRenderPassTest);
1800 
1801 	return renderPassTests.release();
1802 }
1803 
createPipelineLayoutLifetimeTests(tcu::TestContext & testCtx)1804 tcu::TestCaseGroup* createPipelineLayoutLifetimeTests (tcu::TestContext& testCtx)
1805 {
1806 	de::MovePtr<tcu::TestCaseGroup> pipelineLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "lifetime", "Pipeline layout lifetime tests"));
1807 
1808 	addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "graphics", "Test pipeline layout lifetime in graphics pipeline", checkSupport, createPipelineLayoutLifetimeGraphicsSource, pipelineLayoutLifetimeGraphicsTest);
1809 	addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "compute", "Test pipeline layout lifetime in compute pipeline", checkSupport, createPipelineLayoutLifetimeComputeSource, pipelineLayoutLifetimeComputeTest);
1810 	addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_end", "Test destroying the pipeline layout after vkEndCommandBuffer", destroyEarlyComputeSource, destroyAfterEndCommndBufferTest);
1811 	addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_compute_pipeline_construction", "Test destroying the pipeline layout after compute pipeline creation", checkMaintenance4Support, destroyEarlyComputeSource, destroyAfterCreateComputePipelineTest);
1812 	addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_graphics_pipeline_construction", "Test destroying the pipeline layout after graphics pipeline creation", checkMaintenance4Support, createDrawTriangleSource, destroyAfterCreateGraphicsPipelineTest);
1813 
1814 	return pipelineLayoutLifetimeTests.release();
1815 }
1816 
createPipelineLayoutTests(tcu::TestContext & testCtx)1817 tcu::TestCaseGroup* createPipelineLayoutTests (tcu::TestContext& testCtx)
1818 {
1819 	de::MovePtr<tcu::TestCaseGroup> pipelineLayoutTests(new tcu::TestCaseGroup(testCtx, "pipeline_layout", "Pipeline layout tests"));
1820 
1821 	pipelineLayoutTests->addChild(createPipelineLayoutLifetimeTests(testCtx));
1822 
1823 	return pipelineLayoutTests.release();
1824 }
1825 
createPipelineInvalidPointersUnusedStructsTests(tcu::TestContext & testCtx)1826 tcu::TestCaseGroup* createPipelineInvalidPointersUnusedStructsTests (tcu::TestContext& testCtx)
1827 {
1828 	de::MovePtr<tcu::TestCaseGroup> pipelineInvalidPointersUnusedStructsTests(new tcu::TestCaseGroup(testCtx, "pipeline_invalid_pointers_unused_structs", "Create pipelines with invalid pointers for unused structs"));
1829 
1830 	addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "graphics", "Test structs when creating a graphics pipeline", checkSupport, createPipelineInvalidPointersUnusedStructsGraphicsSource, pipelineInvalidPointersUnusedStructsGraphicsTest);
1831 	addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "compute", "Test structs when creating a compute pipeline", checkSupport, createPipelineInvalidPointersUnusedStructsComputeSource, pipelineInvalidPointersUnusedStructsComputeTest);
1832 
1833 	return pipelineInvalidPointersUnusedStructsTests.release();
1834 }
1835 
1836 } // anonymous
1837 
createPipelineTests(tcu::TestContext & testCtx)1838 tcu::TestCaseGroup* createPipelineTests (tcu::TestContext& testCtx)
1839 {
1840 	de::MovePtr<tcu::TestCaseGroup> pipelineTests(new tcu::TestCaseGroup(testCtx, "pipeline", "Descriptor set tests"));
1841 
1842 	pipelineTests->addChild(createrenderpassTests(testCtx));
1843 	pipelineTests->addChild(createPipelineLayoutTests(testCtx));
1844 	pipelineTests->addChild(createPipelineInvalidPointersUnusedStructsTests(testCtx));
1845 
1846 	return pipelineTests.release();
1847 }
1848 
1849 } // api
1850 } // vkt
1851