1/*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2015 Google Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*--------------------------------------------------------------------*/
22
23#include "vkDefs.hpp"
24#include "vktTestCaseUtil.hpp"
25#include "vkBuilderUtil.hpp"
26#include "vkPlatform.hpp"
27#include "vkRefUtil.hpp"
28#include "vkQueryUtil.hpp"
29#include "vkMemUtil.hpp"
30#include "vkDeviceUtil.hpp"
31#include "tcuTextureUtil.hpp"
32#include "vkImageUtil.hpp"
33#include "vkPrograms.hpp"
34#include "vkTypeUtil.hpp"
35#include "vkAllocationCallbackUtil.hpp"
36#include "vktApiCommandBuffersTests.hpp"
37#include "vktApiBufferComputeInstance.hpp"
38#include "vktApiComputeInstanceResultBuffer.hpp"
39#include "deSharedPtr.hpp"
40#include <sstream>
41
42namespace vkt
43{
44namespace api
45{
46namespace
47{
48
49using namespace vk;
50
51typedef de::SharedPtr<vk::Unique<vk::VkEvent> >	VkEventSp;
52
53// Global variables
54const deUint64								INFINITE_TIMEOUT		= ~(deUint64)0u;
55
56
57template <deUint32 NumBuffers>
58class CommandBufferBareTestEnvironment
59{
60public:
61											CommandBufferBareTestEnvironment	(Context&						context,
62																				 VkCommandPoolCreateFlags		commandPoolCreateFlags);
63
64	VkCommandPool							getCommandPool						(void) const					{ return *m_commandPool; }
65	VkCommandBuffer							getCommandBuffer					(deUint32 bufferIndex) const;
66
67protected:
68	Context&								m_context;
69	const VkDevice							m_device;
70	const DeviceInterface&					m_vkd;
71	const VkQueue							m_queue;
72	const deUint32							m_queueFamilyIndex;
73	Allocator&								m_allocator;
74
75	// \note All VkCommandBuffers are allocated from m_commandPool so there is no need
76	//       to free them separately as the auto-generated dtor will do that through
77	//       destroying the pool.
78	Move<VkCommandPool>						m_commandPool;
79	VkCommandBuffer							m_primaryCommandBuffers[NumBuffers];
80};
81
82template <deUint32 NumBuffers>
83CommandBufferBareTestEnvironment<NumBuffers>::CommandBufferBareTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
84	: m_context								(context)
85	, m_device								(context.getDevice())
86	, m_vkd									(context.getDeviceInterface())
87	, m_queue								(context.getUniversalQueue())
88	, m_queueFamilyIndex					(context.getUniversalQueueFamilyIndex())
89	, m_allocator							(context.getDefaultAllocator())
90{
91	const VkCommandPoolCreateInfo			cmdPoolCreateInfo		=
92	{
93		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// VkStructureType             sType;
94		DE_NULL,													// const void*                 pNext;
95		commandPoolCreateFlags,										// VkCommandPoolCreateFlags    flags;
96		m_queueFamilyIndex											// deUint32                    queueFamilyIndex;
97	};
98
99	m_commandPool = createCommandPool(m_vkd, m_device, &cmdPoolCreateInfo, DE_NULL);
100
101	const VkCommandBufferAllocateInfo		cmdBufferAllocateInfo	=
102	{
103		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType             sType;
104		DE_NULL,													// const void*                 pNext;
105		*m_commandPool,												// VkCommandPool               commandPool;
106		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// VkCommandBufferLevel        level;
107		NumBuffers												// deUint32                    commandBufferCount;
108	};
109
110	VK_CHECK(m_vkd.allocateCommandBuffers(m_device, &cmdBufferAllocateInfo, m_primaryCommandBuffers));
111}
112
113template <deUint32 NumBuffers>
114VkCommandBuffer CommandBufferBareTestEnvironment<NumBuffers>::getCommandBuffer(deUint32 bufferIndex) const
115{
116	DE_ASSERT(bufferIndex < NumBuffers);
117	return m_primaryCommandBuffers[bufferIndex];
118}
119
120class CommandBufferRenderPassTestEnvironment : public CommandBufferBareTestEnvironment<1>
121{
122public:
123											CommandBufferRenderPassTestEnvironment	(Context&						context,
124																					 VkCommandPoolCreateFlags		commandPoolCreateFlags);
125
126	VkRenderPass							getRenderPass							(void) const { return *m_renderPass; }
127	VkFramebuffer							getFrameBuffer							(void) const { return *m_frameBuffer; }
128	VkCommandBuffer							getPrimaryCommandBuffer					(void) const { return getCommandBuffer(0); }
129	VkCommandBuffer							getSecondaryCommandBuffer				(void) const { return *m_secondaryCommandBuffer; }
130
131	void									beginPrimaryCommandBuffer				(VkCommandBufferUsageFlags usageFlags);
132	void									beginSecondaryCommandBuffer				(VkCommandBufferUsageFlags usageFlags);
133	void									beginRenderPass							(VkSubpassContents content);
134	void									submitPrimaryCommandBuffer				(void);
135	de::MovePtr<tcu::TextureLevel>			readColorAttachment						(void);
136
137	static const VkImageType				DEFAULT_IMAGE_TYPE;
138	static const VkFormat					DEFAULT_IMAGE_FORMAT;
139	static const VkExtent3D					DEFAULT_IMAGE_SIZE;
140	static const VkRect2D					DEFAULT_IMAGE_AREA;
141
142protected:
143
144	Move<VkImage>							m_colorImage;
145	Move<VkImageView>						m_colorImageView;
146	Move<VkRenderPass>						m_renderPass;
147	Move<VkFramebuffer>						m_frameBuffer;
148	de::MovePtr<Allocation>					m_colorImageMemory;
149	Move<VkCommandBuffer>					m_secondaryCommandBuffer;
150
151};
152
153const VkImageType		CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_TYPE		= VK_IMAGE_TYPE_2D;
154const VkFormat			CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_FORMAT	= VK_FORMAT_R8G8B8A8_UINT;
155const VkExtent3D		CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE		= {255, 255, 1};
156const VkRect2D			CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA		=
157{
158	{ 0u, 0u, },												//	VkOffset2D	offset;
159	{ DEFAULT_IMAGE_SIZE.width,	DEFAULT_IMAGE_SIZE.height },	//	VkExtent2D	extent;
160};
161
162CommandBufferRenderPassTestEnvironment::CommandBufferRenderPassTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
163	: CommandBufferBareTestEnvironment<1>		(context, commandPoolCreateFlags)
164{
165	{
166		const VkAttachmentDescription			colorAttDesc			=
167		{
168			0u,													// VkAttachmentDescriptionFlags		flags;
169			DEFAULT_IMAGE_FORMAT,								// VkFormat							format;
170			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
171			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
172			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
173			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
174			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
175			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
176			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
177		};
178
179		const VkAttachmentDescription			attachments[1]			=
180		{
181			colorAttDesc
182		};
183
184		const VkAttachmentReference				colorAttRef				=
185		{
186			0u,													// deUint32							attachment;
187			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					layout;
188		};
189
190		const VkSubpassDescription				subpassDesc[1]			=
191		{
192			{
193				0u,												// VkSubpassDescriptionFlags		flags;
194				VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint				pipelineBindPoint;
195				0u,												// deUint32							inputAttachmentCount;
196				DE_NULL,										// const VkAttachmentReference*		pInputAttachments;
197				1u,												// deUint32							colorAttachmentCount;
198				&colorAttRef,									// const VkAttachmentReference*		pColorAttachments;
199				DE_NULL,										// const VkAttachmentReference*		pResolveAttachments;
200				DE_NULL,										// const VkAttachmentReference*		depthStencilAttachment;
201				0u,												// deUint32							preserveAttachmentCount;
202				DE_NULL,										// const VkAttachmentReference*		pPreserveAttachments;
203			}
204		};
205
206		const VkRenderPassCreateInfo			renderPassCreateInfo	=
207		{
208			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
209			DE_NULL,											// const void*						pNext;
210			0u,													// VkRenderPassCreateFlags			flags;
211			1u,													// deUint32							attachmentCount;
212			attachments,										// const VkAttachmentDescription*	pAttachments;
213			1u,													// deUint32							subpassCount;
214			subpassDesc,										// const VkSubpassDescription*		pSubpasses;
215			0u,													// deUint32							dependencyCount;
216			DE_NULL,											// const VkSubpassDependency*		pDependencies;
217		};
218
219		m_renderPass = createRenderPass(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
220	}
221
222	{
223		const VkImageCreateInfo					imageCreateInfo			=
224		{
225			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
226			DE_NULL,									// const void*				pNext;
227			0u,											// VkImageCreateFlags		flags;
228			DEFAULT_IMAGE_TYPE,							// VkImageType				imageType;
229			DEFAULT_IMAGE_FORMAT,						// VkFormat					format;
230			DEFAULT_IMAGE_SIZE,							// VkExtent3D				extent;
231			1,											// deUint32					mipLevels;
232			1,											// deUint32					arrayLayers;
233			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
234			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
235			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
236			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
237			VK_IMAGE_USAGE_TRANSFER_DST_BIT,			// VkImageUsageFlags		usage;
238			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
239			1,											// deUint32					queueFamilyIndexCount;
240			&m_queueFamilyIndex,						// const deUint32*			pQueueFamilyIndices;
241			VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
242		};
243
244		m_colorImage = createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
245	}
246
247	m_colorImageMemory = m_allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, *m_colorImage), MemoryRequirement::Any);
248	VK_CHECK(m_vkd.bindImageMemory(m_device, *m_colorImage, m_colorImageMemory->getMemory(), m_colorImageMemory->getOffset()));
249
250	{
251		const VkImageViewCreateInfo				imageViewCreateInfo		=
252		{
253			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
254			DE_NULL,									// const void*					pNext;
255			0u,											// VkImageViewCreateFlags		flags;
256			*m_colorImage,								// VkImage						image;
257			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
258			DEFAULT_IMAGE_FORMAT,						// VkFormat						format;
259			{
260				VK_COMPONENT_SWIZZLE_R,
261				VK_COMPONENT_SWIZZLE_G,
262				VK_COMPONENT_SWIZZLE_B,
263				VK_COMPONENT_SWIZZLE_A
264			},											// VkComponentMapping			components;
265			{
266				VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
267				0u,											// deUint32						baseMipLevel;
268				1u,											// deUint32						mipLevels;
269				0u,											// deUint32						baseArrayLayer;
270				1u,											// deUint32						arraySize;
271			},											// VkImageSubresourceRange		subresourceRange;
272		};
273
274		m_colorImageView = createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL);
275	}
276
277	{
278		const VkImageView						attachmentViews[1]		=
279		{
280			*m_colorImageView
281		};
282
283		const VkFramebufferCreateInfo			framebufferCreateInfo	=
284		{
285			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
286			DE_NULL,									// const void*				pNext;
287			0u,											// VkFramebufferCreateFlags	flags;
288			*m_renderPass,								// VkRenderPass				renderPass;
289			1,											// deUint32					attachmentCount;
290			attachmentViews,							// const VkImageView*		pAttachments;
291			DEFAULT_IMAGE_SIZE.width,					// deUint32					width;
292			DEFAULT_IMAGE_SIZE.height,					// deUint32					height;
293			1u,											// deUint32					layers;
294		};
295
296		m_frameBuffer = createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL);
297	}
298
299	{
300		const VkCommandBufferAllocateInfo		cmdBufferAllocateInfo	=
301		{
302			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType             sType;
303			DE_NULL,													// const void*                 pNext;
304			*m_commandPool,												// VkCommandPool               commandPool;
305			VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// VkCommandBufferLevel        level;
306			1u															// deUint32                    commandBufferCount;
307		};
308
309		m_secondaryCommandBuffer = allocateCommandBuffer(m_vkd, m_device, &cmdBufferAllocateInfo);
310
311	}
312}
313
314void CommandBufferRenderPassTestEnvironment::beginRenderPass(VkSubpassContents content)
315{
316	const VkClearValue						clearValues[1]			=
317	{
318		makeClearValueColorU32(17, 59, 163, 251),
319	};
320
321	const VkRenderPassBeginInfo				renderPassBeginInfo		=
322	{
323		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
324		DE_NULL,												// const void*			pNext;
325		*m_renderPass,											// VkRenderPass			renderPass;
326		*m_frameBuffer,											// VkFramebuffer		framebuffer;
327		DEFAULT_IMAGE_AREA,										// VkRect2D				renderArea;
328		1u,														// deUint32				clearValueCount;
329		clearValues												// const VkClearValue*	pClearValues;
330	};
331
332	m_vkd.cmdBeginRenderPass(m_primaryCommandBuffers[0], &renderPassBeginInfo, content);
333}
334
335void CommandBufferRenderPassTestEnvironment::beginPrimaryCommandBuffer(VkCommandBufferUsageFlags usageFlags)
336{
337	const VkCommandBufferBeginInfo			commandBufferBeginInfo	=
338	{
339		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType                          sType;
340		DE_NULL,												// const void*                              pNext;
341		usageFlags,												// VkCommandBufferUsageFlags                flags;
342		DE_NULL													// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
343	};
344
345	VK_CHECK(m_vkd.beginCommandBuffer(m_primaryCommandBuffers[0], &commandBufferBeginInfo));
346
347}
348
349
350void CommandBufferRenderPassTestEnvironment::beginSecondaryCommandBuffer(VkCommandBufferUsageFlags usageFlags)
351{
352	const VkCommandBufferInheritanceInfo	commandBufferInheritanceInfo =
353	{
354		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,		// VkStructureType                  sType;
355		DE_NULL,												// const void*                      pNext;
356		*m_renderPass,											// VkRenderPass                     renderPass;
357		0u,														// deUint32                         subpass;
358		*m_frameBuffer,											// VkFramebuffer                    framebuffer;
359		VK_FALSE,												// VkBool32                         occlusionQueryEnable;
360		0u,														// VkQueryControlFlags              queryFlags;
361		0u														// VkQueryPipelineStatisticFlags    pipelineStatistics;
362	};
363
364	const VkCommandBufferBeginInfo			commandBufferBeginInfo	=
365	{
366		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType                          sType;
367		DE_NULL,												// const void*                              pNext;
368		usageFlags,												// VkCommandBufferUsageFlags                flags;
369		&commandBufferInheritanceInfo							// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
370	};
371
372	VK_CHECK(m_vkd.beginCommandBuffer(*m_secondaryCommandBuffer, &commandBufferBeginInfo));
373
374}
375
376void CommandBufferRenderPassTestEnvironment::submitPrimaryCommandBuffer(void)
377{
378
379	const VkFenceCreateInfo fenceCreateInfo							=
380	{
381		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,					// VkStructureType       sType;
382		DE_NULL,												// const void*           pNext;
383		0u														// VkFenceCreateFlags    flags;
384	};
385
386	const Unique<VkFence>					fence					(createFence(m_vkd, m_device, &fenceCreateInfo));
387
388
389	const VkSubmitInfo						submitInfo				=
390	{
391		VK_STRUCTURE_TYPE_SUBMIT_INFO,							// VkStructureType                sType;
392		DE_NULL,												// const void*                    pNext;
393		0u,														// deUint32                       waitSemaphoreCount;
394		DE_NULL,												// const VkSemaphore*             pWaitSemaphores;
395		DE_NULL,												// const VkPipelineStageFlags*    pWaitDstStageMask;
396		1u,														// deUint32                       commandBufferCount;
397		m_primaryCommandBuffers,								// const VkCommandBuffer*         pCommandBuffers;
398		0u,														// deUint32                       signalSemaphoreCount;
399		DE_NULL													// const VkSemaphore*             pSignalSemaphores;
400	};
401
402	VK_CHECK(m_vkd.queueSubmit(m_queue, 1, &submitInfo, *fence));
403
404	VK_CHECK(m_vkd.waitForFences(m_device, 1, &fence.get(), VK_TRUE, ~0ull));
405
406}
407
408de::MovePtr<tcu::TextureLevel> CommandBufferRenderPassTestEnvironment::readColorAttachment ()
409{
410	Move<VkBuffer>					buffer;
411	de::MovePtr<Allocation>			bufferAlloc;
412	const tcu::TextureFormat		tcuFormat		= mapVkFormat(DEFAULT_IMAGE_FORMAT);
413	const VkDeviceSize				pixelDataSize	= DEFAULT_IMAGE_SIZE.height * DEFAULT_IMAGE_SIZE.height * tcuFormat.getPixelSize();
414	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(tcuFormat, DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height));
415
416	// Create destination buffer
417	{
418		const VkBufferCreateInfo bufferParams =
419		{
420			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
421			DE_NULL,									// const void*			pNext;
422			0u,											// VkBufferCreateFlags	flags;
423			pixelDataSize,								// VkDeviceSize			size;
424			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
425			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
426			0u,											// deUint32				queueFamilyIndexCount;
427			DE_NULL										// const deUint32*		pQueueFamilyIndices;
428		};
429
430		buffer		= createBuffer(m_vkd, m_device, &bufferParams);
431		bufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, *buffer), MemoryRequirement::HostVisible);
432		VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
433	}
434
435	// Barriers for copying image to buffer
436
437	const VkImageMemoryBarrier imageBarrier =
438	{
439		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
440		DE_NULL,									// const void*				pNext;
441		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
442		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
443		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
444		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
445		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
446		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
447		*m_colorImage,								// VkImage					image;
448		{											// VkImageSubresourceRange	subresourceRange;
449			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
450			0u,							// deUint32				baseMipLevel;
451			1u,							// deUint32				mipLevels;
452			0u,							// deUint32				baseArraySlice;
453			1u							// deUint32				arraySize;
454		}
455	};
456
457	const VkBufferMemoryBarrier bufferBarrier =
458	{
459		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
460		DE_NULL,									// const void*		pNext;
461		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
462		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
463		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
464		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
465		*buffer,									// VkBuffer			buffer;
466		0u,											// VkDeviceSize		offset;
467		pixelDataSize								// VkDeviceSize		size;
468	};
469
470	// Copy image to buffer
471
472	const VkBufferImageCopy copyRegion =
473	{
474		0u,												// VkDeviceSize				bufferOffset;
475		DEFAULT_IMAGE_SIZE.width,						// deUint32					bufferRowLength;
476		DEFAULT_IMAGE_SIZE.height,						// deUint32					bufferImageHeight;
477		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u },		// VkImageSubresourceLayers	imageSubresource;
478		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
479		DEFAULT_IMAGE_SIZE								// VkExtent3D				imageExtent;
480	};
481
482	beginPrimaryCommandBuffer(0);
483	m_vkd.cmdPipelineBarrier(m_primaryCommandBuffers[0], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
484	m_vkd.cmdCopyImageToBuffer(m_primaryCommandBuffers[0], *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
485	m_vkd.cmdPipelineBarrier(m_primaryCommandBuffers[0], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
486	VK_CHECK(m_vkd.endCommandBuffer(m_primaryCommandBuffers[0]));
487
488	submitPrimaryCommandBuffer();
489
490	// Read buffer data
491	invalidateMappedMemoryRange(m_vkd, m_device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
492	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
493
494	return resultLevel;
495}
496
497
498// Testcases
499/********* 19.1. Command Pools (5.1 in VK 1.0 Spec) ***************************/
500tcu::TestStatus createPoolNullParamsTest(Context& context)
501{
502	const VkDevice							vkDevice				= context.getDevice();
503	const DeviceInterface&					vk						= context.getDeviceInterface();
504	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
505
506	const VkCommandPoolCreateInfo			cmdPoolParams			=
507	{
508		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
509		DE_NULL,													// pNext;
510		0u,															// flags;
511		queueFamilyIndex,											// queueFamilyIndex;
512	};
513
514	createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
515
516	return tcu::TestStatus::pass("Command Pool allocated correctly.");
517}
518
519tcu::TestStatus createPoolNonNullAllocatorTest(Context& context)
520{
521	const VkDevice							vkDevice				= context.getDevice();
522	const DeviceInterface&					vk						= context.getDeviceInterface();
523	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
524	const VkAllocationCallbacks*			allocationCallbacks		= getSystemAllocator();
525
526	const VkCommandPoolCreateInfo			cmdPoolParams			=
527	{
528		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
529		DE_NULL,													// pNext;
530		0u,															// flags;
531		queueFamilyIndex,											// queueFamilyIndex;
532	};
533
534	createCommandPool(vk, vkDevice, &cmdPoolParams, allocationCallbacks);
535
536	return tcu::TestStatus::pass("Command Pool allocated correctly.");
537}
538
539tcu::TestStatus createPoolTransientBitTest(Context& context)
540{
541	const VkDevice							vkDevice				= context.getDevice();
542	const DeviceInterface&					vk						= context.getDeviceInterface();
543	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
544
545	const VkCommandPoolCreateInfo			cmdPoolParams			=
546	{
547		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
548		DE_NULL,													// pNext;
549		VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,						// flags;
550		queueFamilyIndex,											// queueFamilyIndex;
551	};
552
553	createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
554
555	return tcu::TestStatus::pass("Command Pool allocated correctly.");
556}
557
558tcu::TestStatus createPoolResetBitTest(Context& context)
559{
560	const VkDevice							vkDevice				= context.getDevice();
561	const DeviceInterface&					vk						= context.getDeviceInterface();
562	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
563
564	const VkCommandPoolCreateInfo			cmdPoolParams			=
565	{
566		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
567		DE_NULL,													// pNext;
568		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
569		queueFamilyIndex,											// queueFamilyIndex;
570	};
571
572	createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
573
574	return tcu::TestStatus::pass("Command Pool allocated correctly.");
575}
576
577tcu::TestStatus resetPoolReleaseResourcesBitTest(Context& context)
578{
579	const VkDevice							vkDevice				= context.getDevice();
580	const DeviceInterface&					vk						= context.getDeviceInterface();
581	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
582
583	const VkCommandPoolCreateInfo			cmdPoolParams			=
584	{
585		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
586		DE_NULL,													// pNext;
587		0u,															// flags;
588		queueFamilyIndex,											// queueFamilyIndex;
589	};
590
591	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
592
593	VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
594
595	return tcu::TestStatus::pass("Command Pool allocated correctly.");
596}
597
598tcu::TestStatus resetPoolNoFlagsTest(Context& context)
599{
600	const VkDevice							vkDevice				= context.getDevice();
601	const DeviceInterface&					vk						= context.getDeviceInterface();
602	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
603
604	const VkCommandPoolCreateInfo			cmdPoolParams			=
605	{
606		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
607		DE_NULL,													// pNext;
608		0u,															// flags;
609		queueFamilyIndex,											// queueFamilyIndex;
610	};
611
612	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
613
614	VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, 0u));
615
616	return tcu::TestStatus::pass("Command Pool allocated correctly.");
617}
618
619bool executeCommandBuffer (const VkDevice			device,
620						   const DeviceInterface&	vk,
621						   const VkQueue			queue,
622						   const VkCommandBuffer	commandBuffer,
623						   const bool				exitBeforeEndCommandBuffer = false)
624{
625	const VkEventCreateInfo			eventCreateInfo			=
626	{
627		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,			//VkStructureType		sType;
628		DE_NULL,										//const void*			pNext;
629		0u												//VkEventCreateFlags	flags;
630	};
631	const Unique<VkEvent>			event					(createEvent(vk, device, &eventCreateInfo));
632	const VkCommandBufferBeginInfo	commandBufferBeginInfo	=
633	{
634		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	//VkStructureType						sType;
635		DE_NULL,										//const void*							pNext;
636		0u,												//VkCommandBufferUsageFlags				flags;
637		(const VkCommandBufferInheritanceInfo*)DE_NULL	//const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
638	};
639
640	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufferBeginInfo));
641	{
642		const VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
643		vk.cmdSetEvent(commandBuffer, *event, stageMask);
644		if (exitBeforeEndCommandBuffer)
645			return exitBeforeEndCommandBuffer;
646	}
647	VK_CHECK(vk.endCommandBuffer(commandBuffer));
648
649	{
650		const VkFenceCreateInfo					fenceCreateInfo	=
651		{
652			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	//VkStructureType		sType;
653			DE_NULL,								//const void*			pNext;
654			0u										//VkFenceCreateFlags	flags;
655		};
656		const Unique<VkFence>					fence			(createFence(vk, device, &fenceCreateInfo));
657		const VkSubmitInfo						submitInfo		=
658		{
659			VK_STRUCTURE_TYPE_SUBMIT_INFO,			// sType
660			DE_NULL,								// pNext
661			0u,										// waitSemaphoreCount
662			DE_NULL,								// pWaitSemaphores
663			(const VkPipelineStageFlags*)DE_NULL,	// pWaitDstStageMask
664			1u,										// commandBufferCount
665			&commandBuffer,							// pCommandBuffers
666			0u,										// signalSemaphoreCount
667			DE_NULL									// pSignalSemaphores
668		};
669
670		// Submit the command buffer to the queue
671		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
672		// wait for end of execution of queue
673		VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
674	}
675	// check if buffer has been executed
676	const VkResult result = vk.getEventStatus(device, *event);
677	return result == VK_EVENT_SET;
678}
679
680tcu::TestStatus resetPoolReuseTest (Context& context)
681{
682	const VkDevice						vkDevice			= context.getDevice();
683	const DeviceInterface&				vk					= context.getDeviceInterface();
684	const deUint32						queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
685	const VkQueue						queue				= context.getUniversalQueue();
686
687	const VkCommandPoolCreateInfo		cmdPoolParams		=
688	{
689		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// sType;
690		DE_NULL,									// pNext;
691		0u,											// flags;
692		queueFamilyIndex							// queueFamilyIndex;
693	};
694	const Unique<VkCommandPool>			cmdPool				(createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
695	const VkCommandBufferAllocateInfo	cmdBufParams		=
696	{
697		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// sType;
698		DE_NULL,										// pNext;
699		*cmdPool,										// commandPool;
700		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// level;
701		1u												// bufferCount;
702	};
703	const Move<VkCommandBuffer>			commandBuffers[]	=
704	{
705		allocateCommandBuffer(vk, vkDevice, &cmdBufParams),
706		allocateCommandBuffer(vk, vkDevice, &cmdBufParams)
707	};
708
709	if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0])))
710		return tcu::TestStatus::fail("Failed");
711	if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1]), true))
712		return tcu::TestStatus::fail("Failed");
713
714	VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
715
716	if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0])))
717		return tcu::TestStatus::fail("Failed");
718	if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1])))
719		return tcu::TestStatus::fail("Failed");
720
721	{
722		const Unique<VkCommandBuffer> afterResetCommandBuffers(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
723		if (!executeCommandBuffer(vkDevice, vk, queue, *afterResetCommandBuffers))
724			return tcu::TestStatus::fail("Failed");
725	}
726
727	return tcu::TestStatus::pass("Passed");
728}
729
730/******** 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) ******************/
731tcu::TestStatus allocatePrimaryBufferTest(Context& context)
732{
733	const VkDevice							vkDevice				= context.getDevice();
734	const DeviceInterface&					vk						= context.getDeviceInterface();
735	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
736
737	const VkCommandPoolCreateInfo			cmdPoolParams			=
738	{
739		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
740		DE_NULL,													// pNext;
741		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
742		queueFamilyIndex,											// queueFamilyIndex;
743	};
744	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
745
746	// Command buffer
747	const VkCommandBufferAllocateInfo		cmdBufParams			=
748	{
749		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
750		DE_NULL,													// pNext;
751		*cmdPool,													// commandPool;
752		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
753		1u,															// bufferCount;
754	};
755	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
756
757	return tcu::TestStatus::pass("Buffer was created correctly.");
758}
759
760tcu::TestStatus allocateManyPrimaryBuffersTest(Context& context)
761{
762
763	const VkDevice							vkDevice				= context.getDevice();
764	const DeviceInterface&					vk						= context.getDeviceInterface();
765	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
766
767	const VkCommandPoolCreateInfo			cmdPoolParams			=
768	{
769		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
770		DE_NULL,													//	const void*					pNext;
771		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
772		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
773	};
774	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
775
776	// \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities.
777#if (DE_PTR_SIZE == 4)
778	const unsigned minCommandBuffer = 1024;
779#else
780	const unsigned minCommandBuffer = 10000;
781#endif
782
783	// Command buffer
784	const VkCommandBufferAllocateInfo		cmdBufParams			=
785	{
786		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
787		DE_NULL,													//	const void*					pNext;
788		*cmdPool,													//	VkCommandPool				pool;
789		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
790		minCommandBuffer,											//	uint32_t					bufferCount;
791	};
792
793	// do not keep the handles to buffers, as they will be freed with command pool
794
795	// allocate the minimum required amount of buffers
796	VkCommandBuffer cmdBuffers[minCommandBuffer];
797	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
798
799	std::ostringstream out;
800	out << "allocateManyPrimaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
801
802	return tcu::TestStatus::pass(out.str());
803}
804
805tcu::TestStatus allocateSecondaryBufferTest(Context& context)
806{
807	const VkDevice							vkDevice				= context.getDevice();
808	const DeviceInterface&					vk						= context.getDeviceInterface();
809	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
810
811	const VkCommandPoolCreateInfo			cmdPoolParams			=
812	{
813		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
814		DE_NULL,													// pNext;
815		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
816		queueFamilyIndex,											// queueFamilyIndex;
817	};
818	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
819
820	// Command buffer
821	const VkCommandBufferAllocateInfo		cmdBufParams			=
822	{
823		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
824		DE_NULL,													// pNext;
825		*cmdPool,													// commandPool;
826		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
827		1u,															// bufferCount;
828	};
829	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
830
831	return tcu::TestStatus::pass("Buffer was created correctly.");
832}
833
834tcu::TestStatus allocateManySecondaryBuffersTest(Context& context)
835{
836
837	const VkDevice							vkDevice				= context.getDevice();
838	const DeviceInterface&					vk						= context.getDeviceInterface();
839	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
840
841	const VkCommandPoolCreateInfo			cmdPoolParams			=
842	{
843		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
844		DE_NULL,													//	const void*					pNext;
845		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
846		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
847	};
848	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
849
850	// \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities.
851#if (DE_PTR_SIZE == 4)
852	const unsigned minCommandBuffer = 1024;
853#else
854	const unsigned minCommandBuffer = 10000;
855#endif
856
857	// Command buffer
858	const VkCommandBufferAllocateInfo		cmdBufParams			=
859	{
860		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
861		DE_NULL,													//	const void*					pNext;
862		*cmdPool,													//	VkCommandPool				pool;
863		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
864		minCommandBuffer,											//	uint32_t					bufferCount;
865	};
866
867	// do not keep the handles to buffers, as they will be freed with command pool
868
869	// allocate the minimum required amount of buffers
870	VkCommandBuffer cmdBuffers[minCommandBuffer];
871	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
872
873	std::ostringstream out;
874	out << "allocateManySecondaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
875
876	return tcu::TestStatus::pass(out.str());
877}
878
879tcu::TestStatus executePrimaryBufferTest(Context& context)
880{
881	const VkDevice							vkDevice				= context.getDevice();
882	const DeviceInterface&					vk						= context.getDeviceInterface();
883	const VkQueue							queue					= context.getUniversalQueue();
884	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
885
886	const VkCommandPoolCreateInfo			cmdPoolParams			=
887	{
888		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
889		DE_NULL,													//	const void*					pNext;
890		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
891		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
892	};
893	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
894
895	// Command buffer
896	const VkCommandBufferAllocateInfo		cmdBufParams			=
897	{
898		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
899		DE_NULL,													//	const void*					pNext;
900		*cmdPool,													//	VkCommandPool				pool;
901		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
902		1u,															//	uint32_t					bufferCount;
903	};
904	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
905	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
906	{
907		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
908		DE_NULL,
909		0,															// flags
910		(const VkCommandBufferInheritanceInfo*)DE_NULL,
911	};
912
913	// Fill create info struct for event
914	const VkEventCreateInfo					eventCreateInfo			=
915	{
916		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
917		DE_NULL,
918		0u,
919	};
920
921	// create event that will be used to check if secondary command buffer has been executed
922	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
923
924	// reset event
925	VK_CHECK(vk.resetEvent(vkDevice, *event));
926
927	// record primary command buffer
928	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
929	{
930		// allow execution of event during every stage of pipeline
931		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
932
933		// record setting event
934		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
935	}
936	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
937
938	const VkFenceCreateInfo					fenceCreateInfo			=
939	{
940		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
941		DE_NULL,
942		0u,															// flags
943	};
944
945	// create fence to wait for execution of queue
946	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
947
948	const VkSubmitInfo						submitInfo				=
949	{
950		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
951		DE_NULL,													// pNext
952		0u,															// waitSemaphoreCount
953		DE_NULL,													// pWaitSemaphores
954		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
955		1,															// commandBufferCount
956		&primCmdBuf.get(),											// pCommandBuffers
957		0u,															// signalSemaphoreCount
958		DE_NULL,													// pSignalSemaphores
959	};
960
961	// Submit the command buffer to the queue
962	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
963
964	// wait for end of execution of queue
965	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
966
967	// check if buffer has been executed
968	VkResult result = vk.getEventStatus(vkDevice,*event);
969	if (result == VK_EVENT_SET)
970		return tcu::TestStatus::pass("Execute Primary Command Buffer succeeded");
971
972	return tcu::TestStatus::fail("Execute Primary Command Buffer FAILED");
973}
974
975tcu::TestStatus executeLargePrimaryBufferTest(Context& context)
976{
977	const VkDevice							vkDevice				= context.getDevice();
978	const DeviceInterface&					vk						= context.getDeviceInterface();
979	const VkQueue							queue					= context.getUniversalQueue();
980	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
981	const deUint32							LARGE_BUFFER_SIZE		= 10000;
982
983	const VkCommandPoolCreateInfo			cmdPoolParams			=
984	{
985		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
986		DE_NULL,													//	const void*					pNext;
987		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
988		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
989	};
990	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
991
992	// Command buffer
993	const VkCommandBufferAllocateInfo		cmdBufParams			=
994	{
995		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
996		DE_NULL,													//	const void*					pNext;
997		*cmdPool,													//	VkCommandPool				pool;
998		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
999		1u,															//	uint32_t					bufferCount;
1000	};
1001	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1002	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1003	{
1004		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1005		DE_NULL,
1006		0,															// flags
1007		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1008	};
1009
1010	// Fill create info struct for event
1011	const VkEventCreateInfo					eventCreateInfo			=
1012	{
1013		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1014		DE_NULL,
1015		0u,
1016	};
1017
1018	std::vector<VkEventSp>					events;
1019	for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
1020		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL))));
1021
1022	// record primary command buffer
1023	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
1024	{
1025		// set all the events
1026		for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
1027		{
1028			vk.cmdSetEvent(*primCmdBuf, events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1029		}
1030	}
1031	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
1032
1033	const VkFenceCreateInfo					fenceCreateInfo			=
1034	{
1035		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1036		DE_NULL,
1037		0u,															// flags
1038	};
1039
1040	// create fence to wait for execution of queue
1041	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1042
1043	const VkSubmitInfo						submitInfo				=
1044	{
1045		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1046		DE_NULL,													// pNext
1047		0u,															// waitSemaphoreCount
1048		DE_NULL,													// pWaitSemaphores
1049		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1050		1,															// commandBufferCount
1051		&primCmdBuf.get(),											// pCommandBuffers
1052		0u,															// signalSemaphoreCount
1053		DE_NULL,													// pSignalSemaphores
1054	};
1055
1056	// Submit the command buffer to the queue
1057	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1058
1059	// wait for end of execution of queue
1060	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1061
1062	// check if the buffer was executed correctly - all events had their status
1063	// changed
1064	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
1065
1066	for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
1067	{
1068		if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
1069		{
1070			testResult = tcu::TestStatus::fail("An event was not set.");
1071			break;
1072		}
1073	}
1074
1075	if (!testResult.isComplete())
1076		testResult = tcu::TestStatus::pass("All events set correctly.");
1077
1078	return testResult;
1079}
1080
1081tcu::TestStatus resetBufferImplicitlyTest(Context& context)
1082{
1083	const VkDevice							vkDevice				= context.getDevice();
1084	const DeviceInterface&					vk						= context.getDeviceInterface();
1085	const VkQueue							queue					= context.getUniversalQueue();
1086	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1087
1088	const VkCommandPoolCreateInfo			cmdPoolParams			=
1089	{
1090		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
1091		DE_NULL,													// pNext;
1092		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
1093		queueFamilyIndex,											// queueFamilyIndex;
1094	};
1095	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1096
1097	// Command buffer
1098	const VkCommandBufferAllocateInfo		cmdBufParams			=
1099	{
1100		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
1101		DE_NULL,													// pNext;
1102		*cmdPool,													// pool;
1103		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
1104		1u,															// bufferCount;
1105	};
1106	const Unique<VkCommandBuffer>			cmdBuf						(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1107
1108	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
1109	{
1110		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
1111		DE_NULL,													// pNext
1112		0u,															// flags
1113		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1114	};
1115
1116	const VkEventCreateInfo					eventCreateInfo			=
1117	{
1118		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,						// sType;
1119		DE_NULL,													// pNext;
1120		0u,															// flags;
1121	};
1122	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1123
1124	// Put the command buffer in recording state.
1125	VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo));
1126	{
1127		// Set the event
1128		vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1129	}
1130	VK_CHECK(vk.endCommandBuffer(*cmdBuf));
1131
1132	// We'll use a fence to wait for the execution of the queue
1133	const VkFenceCreateInfo					fenceCreateInfo			=
1134	{
1135		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,						// sType;
1136		DE_NULL,													// pNext;
1137		0u,															// flags
1138	};
1139	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1140
1141	const VkSubmitInfo						submitInfo				=
1142	{
1143		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1144		DE_NULL,													// pNext
1145		0u,															// waitSemaphoreCount
1146		DE_NULL,													// pWaitSemaphores
1147		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1148		1u,															// commandBufferCount
1149		&cmdBuf.get(),												// pCommandBuffers
1150		0u,															// signalSemaphoreCount
1151		DE_NULL,													// pSignalSemaphores
1152	};
1153
1154	// Submitting the command buffer that sets the event to the queue
1155	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
1156
1157	// Waiting for the queue to finish executing
1158	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
1159	// Reset the fence so that we can reuse it
1160	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
1161
1162	// Check if the buffer was executed
1163	if (vk.getEventStatus(vkDevice, *event) != VK_EVENT_SET)
1164		return tcu::TestStatus::fail("Failed to set the event.");
1165
1166	// Reset the event
1167	vk.resetEvent(vkDevice, *event);
1168	if(vk.getEventStatus(vkDevice, *event) != VK_EVENT_RESET)
1169		return tcu::TestStatus::fail("Failed to reset the event.");
1170
1171	// Reset the command buffer by putting it in recording state again. This
1172	// should empty the command buffer.
1173	VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo));
1174	VK_CHECK(vk.endCommandBuffer(*cmdBuf));
1175
1176	// Submit the command buffer after resetting. It should have no commands
1177	// recorded, so the event should remain unsignaled.
1178	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
1179	// Waiting for the queue to finish executing
1180	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
1181
1182	// Check if the event remained unset.
1183	if(vk.getEventStatus(vkDevice, *event) == VK_EVENT_RESET)
1184		return tcu::TestStatus::pass("Buffer was reset correctly.");
1185	else
1186		return tcu::TestStatus::fail("Buffer was not reset correctly.");
1187}
1188
1189using  de::SharedPtr;
1190typedef SharedPtr<Unique<VkEvent> >			VkEventShared;
1191
1192template<typename T>
1193inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
1194{
1195	return SharedPtr<Unique<T> >(new Unique<T>(move));
1196}
1197
1198bool submitAndCheck (Context& context, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
1199{
1200	const VkDevice							vkDevice	= context.getDevice();
1201	const DeviceInterface&					vk			= context.getDeviceInterface();
1202	const VkQueue							queue		= context.getUniversalQueue();
1203
1204	const VkFenceCreateInfo				fenceCreateInfo	=
1205	{
1206		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,		// sType;
1207		DE_NULL,									// pNext;
1208		0u,											// flags
1209	};
1210	const Unique<VkFence>				fence			(createFence(vk, vkDevice, &fenceCreateInfo));
1211
1212	const VkSubmitInfo					submitInfo		=
1213	{
1214		VK_STRUCTURE_TYPE_SUBMIT_INFO,				// sType
1215		DE_NULL,									// pNext
1216		0u,											// waitSemaphoreCount
1217		DE_NULL,									// pWaitSemaphores
1218		(const VkPipelineStageFlags*)DE_NULL,		// pWaitDstStageMask
1219		static_cast<deUint32>(cmdBuffers.size()),	// commandBufferCount
1220		&cmdBuffers[0],								// pCommandBuffers
1221		0u,											// signalSemaphoreCount
1222		DE_NULL,									// pSignalSemaphores
1223	};
1224
1225	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
1226	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
1227
1228	for(int eventNdx = 0; eventNdx < static_cast<int>(events.size()); ++eventNdx)
1229	{
1230		if (vk.getEventStatus(vkDevice, **events[eventNdx]) != VK_EVENT_SET)
1231			return false;
1232		vk.resetEvent(vkDevice, **events[eventNdx]);
1233	}
1234
1235	return true;
1236}
1237
1238void createCommadBuffers (const DeviceInterface&		vk,
1239						  const VkDevice				vkDevice,
1240						  deUint32						bufferCount,
1241						  VkCommandPool					pool,
1242						  const VkCommandBufferLevel	cmdBufferLevel,
1243						  VkCommandBuffer*				pCommandBuffers)
1244{
1245	const VkCommandBufferAllocateInfo		cmdBufParams	=
1246	{
1247		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	//	VkStructureType				sType;
1248		DE_NULL,										//	const void*					pNext;
1249		pool,											//	VkCommandPool				pool;
1250		cmdBufferLevel,									//	VkCommandBufferLevel		level;
1251		bufferCount,									//	uint32_t					bufferCount;
1252	};
1253	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, pCommandBuffers));
1254}
1255
1256void addCommandsToBuffer (const DeviceInterface& vk, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
1257{
1258	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
1259	{
1260		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1261		DE_NULL,
1262		(VkRenderPass)0u,								// renderPass
1263		0u,												// subpass
1264		(VkFramebuffer)0u,								// framebuffer
1265		VK_FALSE,										// occlusionQueryEnable
1266		(VkQueryControlFlags)0u,						// queryFlags
1267		(VkQueryPipelineStatisticFlags)0u,				// pipelineStatistics
1268	};
1269
1270	const VkCommandBufferBeginInfo		cmdBufBeginInfo	=
1271	{
1272		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// sType
1273		DE_NULL,										// pNext
1274		0u,												// flags
1275		&secCmdBufInheritInfo,							// pInheritanceInfo;
1276	};
1277
1278	for(int bufferNdx = 0; bufferNdx < static_cast<int>(cmdBuffers.size()); ++bufferNdx)
1279	{
1280		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[bufferNdx], &cmdBufBeginInfo));
1281		vk.cmdSetEvent(cmdBuffers[bufferNdx], **events[bufferNdx % events.size()], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1282		VK_CHECK(vk.endCommandBuffer(cmdBuffers[bufferNdx]));
1283	}
1284}
1285
1286bool executeSecondaryCmdBuffer (Context&						context,
1287								VkCommandPool					pool,
1288								std::vector<VkCommandBuffer>&	cmdBuffersSecondary,
1289								std::vector <VkEventShared>&	events)
1290{
1291	const VkDevice					vkDevice		= context.getDevice();
1292	const DeviceInterface&			vk				= context.getDeviceInterface();
1293	std::vector<VkCommandBuffer>	cmdBuffer		(1);
1294	const VkCommandBufferBeginInfo	cmdBufBeginInfo	=
1295	{
1296		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// sType
1297		DE_NULL,										// pNext
1298		0u,												// flags
1299		(const VkCommandBufferInheritanceInfo*)DE_NULL,	// pInheritanceInfo;
1300	};
1301
1302	createCommadBuffers(vk, vkDevice, 1u, pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, &cmdBuffer[0]);
1303	VK_CHECK(vk.beginCommandBuffer(cmdBuffer[0], &cmdBufBeginInfo));
1304	vk.cmdExecuteCommands(cmdBuffer[0], static_cast<deUint32>(cmdBuffersSecondary.size()), &cmdBuffersSecondary[0]);
1305	VK_CHECK(vk.endCommandBuffer(cmdBuffer[0]));
1306
1307	bool returnValue = submitAndCheck(context, cmdBuffer, events);
1308	vk.freeCommandBuffers(vkDevice, pool, 1u, &cmdBuffer[0]);
1309	return returnValue;
1310}
1311
1312tcu::TestStatus trimCommandPoolTest (Context& context, const VkCommandBufferLevel cmdBufferLevel)
1313{
1314	if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1"))
1315		TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1316
1317	const VkDevice							vkDevice				= context.getDevice();
1318	const DeviceInterface&					vk						= context.getDeviceInterface();
1319	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1320
1321	//test parameters
1322	const deUint32							cmdBufferIterationCount	= 300u;
1323	const deUint32							cmdBufferCount			= 10u;
1324
1325	const VkCommandPoolCreateInfo			cmdPoolParams			=
1326	{
1327		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
1328		DE_NULL,													// pNext;
1329		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
1330		queueFamilyIndex,											// queueFamilyIndex;
1331	};
1332	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1333
1334	const VkEventCreateInfo					eventCreateInfo			=
1335	{
1336		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,						// sType;
1337		DE_NULL,													// pNext;
1338		0u,															// flags;
1339	};
1340
1341	std::vector <VkEventShared>				events;
1342	for (deUint32 ndx = 0u; ndx < cmdBufferCount; ++ndx)
1343		events.push_back(makeSharedPtr(createEvent(vk, vkDevice, &eventCreateInfo)));
1344
1345	{
1346		std::vector<VkCommandBuffer> cmdBuffers(cmdBufferCount);
1347		createCommadBuffers(vk, vkDevice, cmdBufferCount, *cmdPool, cmdBufferLevel, &cmdBuffers[0]);
1348
1349		for (deUint32 cmdBufferIterationrNdx = 0; cmdBufferIterationrNdx < cmdBufferIterationCount; ++cmdBufferIterationrNdx)
1350		{
1351			addCommandsToBuffer(vk, cmdBuffers, events);
1352
1353			//Peak, situation when we use a lot more command buffers
1354			if (cmdBufferIterationrNdx % 10u == 0)
1355			{
1356				std::vector<VkCommandBuffer> cmdBuffersPeak(cmdBufferCount * 10u);
1357				createCommadBuffers(vk, vkDevice, static_cast<deUint32>(cmdBuffersPeak.size()), *cmdPool, cmdBufferLevel, &cmdBuffersPeak[0]);
1358				addCommandsToBuffer(vk, cmdBuffersPeak, events);
1359
1360				switch(cmdBufferLevel)
1361				{
1362					case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1363						if (!submitAndCheck(context, cmdBuffersPeak, events))
1364							return tcu::TestStatus::fail("Fail");
1365						break;
1366					case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1367						if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffersPeak, events))
1368							return tcu::TestStatus::fail("Fail");
1369						break;
1370					default:
1371						DE_ASSERT(0);
1372				}
1373				vk.freeCommandBuffers(vkDevice, *cmdPool, static_cast<deUint32>(cmdBuffersPeak.size()), &cmdBuffersPeak[0]);
1374			}
1375
1376			vk.trimCommandPoolKHR(vkDevice, *cmdPool, (VkCommandPoolTrimFlagsKHR)0);
1377
1378			switch(cmdBufferLevel)
1379			{
1380				case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1381					if (!submitAndCheck(context, cmdBuffers, events))
1382						return tcu::TestStatus::fail("Fail");
1383					break;
1384				case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1385					if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffers, events))
1386						return tcu::TestStatus::fail("Fail");
1387					break;
1388				default:
1389					DE_ASSERT(0);
1390			}
1391
1392			for (deUint32 bufferNdx = cmdBufferIterationrNdx % 3u; bufferNdx < cmdBufferCount; bufferNdx+=2u)
1393			{
1394				vk.freeCommandBuffers(vkDevice, *cmdPool, 1u, &cmdBuffers[bufferNdx]);
1395				createCommadBuffers(vk, vkDevice, 1u, *cmdPool, cmdBufferLevel, &cmdBuffers[bufferNdx]);
1396			}
1397		}
1398	}
1399
1400	return tcu::TestStatus::pass("Pass");
1401}
1402
1403/******** 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) *****************/
1404tcu::TestStatus recordSinglePrimaryBufferTest(Context& context)
1405{
1406	const VkDevice							vkDevice				= context.getDevice();
1407	const DeviceInterface&					vk						= context.getDeviceInterface();
1408	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1409
1410	const VkCommandPoolCreateInfo			cmdPoolParams			=
1411	{
1412		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1413		DE_NULL,													//	const void*					pNext;
1414		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1415		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1416	};
1417	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1418
1419	// Command buffer
1420	const VkCommandBufferAllocateInfo		cmdBufParams			=
1421	{
1422		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
1423		DE_NULL,													//	const void*					pNext;
1424		*cmdPool,													//	VkCommandPool				pool;
1425		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1426		1u,															//	uint32_t					bufferCount;
1427	};
1428	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1429
1430	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1431	{
1432		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1433		DE_NULL,
1434		0,															// flags
1435		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1436	};
1437
1438	// Fill create info struct for event
1439	const VkEventCreateInfo					eventCreateInfo			=
1440	{
1441		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1442		DE_NULL,
1443		0u,
1444	};
1445
1446	// create event that will be used to check if secondary command buffer has been executed
1447	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1448
1449	// record primary command buffer
1450	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
1451	{
1452		// record setting event
1453		vk.cmdSetEvent(*primCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1454	}
1455	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
1456
1457	return tcu::TestStatus::pass("Primary buffer recorded successfully.");
1458}
1459
1460tcu::TestStatus recordLargePrimaryBufferTest(Context &context)
1461{
1462
1463	const VkDevice							vkDevice				= context.getDevice();
1464	const DeviceInterface&					vk						= context.getDeviceInterface();
1465	const VkQueue							queue					= context.getUniversalQueue();
1466	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1467
1468	const VkCommandPoolCreateInfo			cmdPoolParams			=
1469	{
1470		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1471		DE_NULL,													//	const void*					pNext;
1472		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1473		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1474	};
1475	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1476
1477	// Command buffer
1478	const VkCommandBufferAllocateInfo		cmdBufParams			=
1479	{
1480		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
1481		DE_NULL,													//	const void*					pNext;
1482		*cmdPool,													//	VkCommandPool				pool;
1483		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1484		1u,															//	uint32_t					bufferCount;
1485	};
1486	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1487	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1488	{
1489		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1490		DE_NULL,
1491		0,															// flags
1492		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1493	};
1494
1495	// Fill create info struct for event
1496	const VkEventCreateInfo					eventCreateInfo			=
1497	{
1498		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1499		DE_NULL,
1500		0u,
1501	};
1502
1503	// create event that will be used to check if secondary command buffer has been executed
1504	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1505
1506	// reset event
1507	VK_CHECK(vk.resetEvent(vkDevice, *event));
1508
1509	// record primary command buffer
1510	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
1511	{
1512		// allow execution of event during every stage of pipeline
1513		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1514
1515		// define minimal amount of commands to accept
1516		const long long unsigned minNumCommands = 10000llu;
1517
1518		for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1519		{
1520			// record setting event
1521			vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1522
1523			// record resetting event
1524			vk.cmdResetEvent(*primCmdBuf, *event,stageMask);
1525		};
1526
1527	}
1528	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
1529
1530	const VkFenceCreateInfo					fenceCreateInfo			=
1531	{
1532		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1533		DE_NULL,
1534		0u,															// flags
1535	};
1536
1537	// create fence to wait for execution of queue
1538	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1539
1540	const VkSubmitInfo						submitInfo				=
1541	{
1542		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1543		DE_NULL,													// pNext
1544		0u,															// waitSemaphoreCount
1545		DE_NULL,													// pWaitSemaphores
1546		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1547		1,															// commandBufferCount
1548		&primCmdBuf.get(),											// pCommandBuffers
1549		0u,															// signalSemaphoreCount
1550		DE_NULL,													// pSignalSemaphores
1551	};
1552
1553	// Submit the command buffer to the queue
1554	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1555
1556	// wait for end of execution of queue
1557	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1558
1559	return tcu::TestStatus::pass("hugeTest succeeded");
1560}
1561
1562tcu::TestStatus recordSingleSecondaryBufferTest(Context& context)
1563{
1564	const VkDevice							vkDevice				= context.getDevice();
1565	const DeviceInterface&					vk						= context.getDeviceInterface();
1566	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1567
1568	const VkCommandPoolCreateInfo			cmdPoolParams			=
1569	{
1570		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1571		DE_NULL,													//	const void*					pNext;
1572		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1573		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1574	};
1575	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1576
1577	// Command buffer
1578	const VkCommandBufferAllocateInfo		cmdBufParams			=
1579	{
1580		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
1581		DE_NULL,													//	const void*					pNext;
1582		*cmdPool,													//	VkCommandPool				pool;
1583		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
1584		1u,															//	uint32_t					bufferCount;
1585	};
1586	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1587
1588	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
1589	{
1590		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1591		DE_NULL,
1592		(VkRenderPass)0u,											// renderPass
1593		0u,															// subpass
1594		(VkFramebuffer)0u,											// framebuffer
1595		VK_FALSE,													// occlusionQueryEnable
1596		(VkQueryControlFlags)0u,									// queryFlags
1597		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
1598	};
1599	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
1600	{
1601		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1602		DE_NULL,
1603		0,															// flags
1604		&secCmdBufInheritInfo,
1605	};
1606
1607	// Fill create info struct for event
1608	const VkEventCreateInfo					eventCreateInfo			=
1609	{
1610		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1611		DE_NULL,
1612		0u,
1613	};
1614
1615	// create event that will be used to check if secondary command buffer has been executed
1616	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1617
1618	// record primary command buffer
1619	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1620	{
1621		// record setting event
1622		vk.cmdSetEvent(*secCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1623	}
1624	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
1625
1626	return tcu::TestStatus::pass("Secondary buffer recorded successfully.");
1627}
1628
1629tcu::TestStatus recordLargeSecondaryBufferTest(Context &context)
1630{
1631
1632	const VkDevice							vkDevice				= context.getDevice();
1633	const DeviceInterface&					vk						= context.getDeviceInterface();
1634	const VkQueue							queue					= context.getUniversalQueue();
1635	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1636
1637	const VkCommandPoolCreateInfo			cmdPoolParams			=
1638	{
1639		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1640		DE_NULL,													//	const void*					pNext;
1641		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1642		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1643	};
1644	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1645
1646	// Command buffer
1647	const VkCommandBufferAllocateInfo		cmdBufParams			=
1648	{
1649		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
1650		DE_NULL,													//	const void*					pNext;
1651		*cmdPool,													//	VkCommandPool				pool;
1652		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1653		1u,															//	uint32_t					bufferCount;
1654	};
1655	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1656	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1657	{
1658		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1659		DE_NULL,
1660		0,															// flags
1661		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1662	};
1663
1664	// Fill create info struct for event
1665	const VkEventCreateInfo					eventCreateInfo			=
1666	{
1667		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1668		DE_NULL,
1669		0u,
1670	};
1671
1672	// create event that will be used to check if secondary command buffer has been executed
1673	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1674
1675	// reset event
1676	VK_CHECK(vk.resetEvent(vkDevice, *event));
1677
1678	// record primary command buffer
1679	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
1680	{
1681		// allow execution of event during every stage of pipeline
1682		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1683
1684		// define minimal amount of commands to accept
1685		const long long unsigned minNumCommands = 10000llu;
1686
1687		for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1688		{
1689			// record setting event
1690			vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1691
1692			// record resetting event
1693			vk.cmdResetEvent(*primCmdBuf, *event,stageMask);
1694		};
1695
1696
1697	}
1698	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
1699
1700	const VkFenceCreateInfo					fenceCreateInfo			=
1701	{
1702		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1703		DE_NULL,
1704		0u,															// flags
1705	};
1706
1707	// create fence to wait for execution of queue
1708	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1709
1710	const VkSubmitInfo						submitInfo				=
1711	{
1712		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1713		DE_NULL,													// pNext
1714		0u,															// waitSemaphoreCount
1715		DE_NULL,													// pWaitSemaphores
1716		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1717		1,															// commandBufferCount
1718		&primCmdBuf.get(),											// pCommandBuffers
1719		0u,															// signalSemaphoreCount
1720		DE_NULL,													// pSignalSemaphores
1721	};
1722
1723	// Submit the command buffer to the queue
1724	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1725
1726	// wait for end of execution of queue
1727	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1728
1729	return tcu::TestStatus::pass("hugeTest succeeded");
1730}
1731
1732tcu::TestStatus submitPrimaryBufferTwiceTest(Context& context)
1733{
1734
1735	const VkDevice							vkDevice				= context.getDevice();
1736	const DeviceInterface&					vk						= context.getDeviceInterface();
1737	const VkQueue							queue					= context.getUniversalQueue();
1738	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1739
1740	const VkCommandPoolCreateInfo			cmdPoolParams			=
1741	{
1742		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1743		DE_NULL,													//	const void*					pNext;
1744		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1745		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1746	};
1747	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1748
1749	// Command buffer
1750	const VkCommandBufferAllocateInfo		cmdBufParams			=
1751	{
1752		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1753		DE_NULL,													//	const void*				pNext;
1754		*cmdPool,													//	VkCommandPool				pool;
1755		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1756		1u,															//	uint32_t					bufferCount;
1757	};
1758	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1759	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1760	{
1761		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1762		DE_NULL,
1763		0,															// flags
1764		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1765	};
1766
1767	// Fill create info struct for event
1768	const VkEventCreateInfo					eventCreateInfo			=
1769	{
1770		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1771		DE_NULL,
1772		0u,
1773	};
1774
1775	// create event that will be used to check if secondary command buffer has been executed
1776	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1777
1778	// reset event
1779	VK_CHECK(vk.resetEvent(vkDevice, *event));
1780
1781	// record primary command buffer
1782	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
1783	{
1784		// allow execution of event during every stage of pipeline
1785		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1786
1787		// record setting event
1788		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1789	}
1790	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
1791
1792	const VkFenceCreateInfo					fenceCreateInfo			=
1793	{
1794		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1795		DE_NULL,
1796		0u,															// flags
1797	};
1798
1799	// create fence to wait for execution of queue
1800	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1801
1802	const VkSubmitInfo						submitInfo				=
1803	{
1804		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1805		DE_NULL,													// pNext
1806		0u,															// waitSemaphoreCount
1807		DE_NULL,													// pWaitSemaphores
1808		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1809		1,															// commandBufferCount
1810		&primCmdBuf.get(),											// pCommandBuffers
1811		0u,															// signalSemaphoreCount
1812		DE_NULL,													// pSignalSemaphores
1813	};
1814
1815	// submit primary buffer
1816	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1817
1818	// wait for end of execution of queue
1819	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1820	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
1821	// check if buffer has been executed
1822	VkResult result = vk.getEventStatus(vkDevice,*event);
1823	if (result != VK_EVENT_SET)
1824		return tcu::TestStatus::fail("Submit Twice Test FAILED");
1825
1826	// reset event
1827	VK_CHECK(vk.resetEvent(vkDevice, *event));
1828
1829	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1830
1831	// wait for end of execution of queue
1832	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1833
1834	// check if buffer has been executed
1835	result = vk.getEventStatus(vkDevice,*event);
1836	if (result != VK_EVENT_SET)
1837		return tcu::TestStatus::fail("Submit Twice Test FAILED");
1838	else
1839		return tcu::TestStatus::pass("Submit Twice Test succeeded");
1840}
1841
1842tcu::TestStatus submitSecondaryBufferTwiceTest(Context& context)
1843{
1844
1845	const VkDevice							vkDevice				= context.getDevice();
1846	const DeviceInterface&					vk						= context.getDeviceInterface();
1847	const VkQueue							queue					= context.getUniversalQueue();
1848	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1849
1850	const VkCommandPoolCreateInfo			cmdPoolParams			=
1851	{
1852		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1853		DE_NULL,													//	const void*					pNext;
1854		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1855		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1856	};
1857
1858	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1859
1860	// Command buffer
1861	const VkCommandBufferAllocateInfo		cmdBufParams			=
1862	{
1863		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1864		DE_NULL,													//	const void*				pNext;
1865		*cmdPool,													//	VkCommandPool				pool;
1866		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1867		1u,															//	uint32_t					bufferCount;
1868	};
1869
1870	const Unique<VkCommandBuffer>			primCmdBuf1				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1871	const Unique<VkCommandBuffer>			primCmdBuf2				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1872
1873	// Secondary Command buffer
1874	const VkCommandBufferAllocateInfo		secCmdBufParams			=
1875	{
1876		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1877		DE_NULL,													//	const void*				pNext;
1878		*cmdPool,													//	VkCommandPool				pool;
1879		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
1880		1u,															//	uint32_t					bufferCount;
1881	};
1882	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1883
1884	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
1885	{
1886		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1887		DE_NULL,
1888		0,															// flags
1889		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1890	};
1891
1892	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
1893	{
1894		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1895		DE_NULL,
1896		(VkRenderPass)0u,											// renderPass
1897		0u,															// subpass
1898		(VkFramebuffer)0u,											// framebuffer
1899		VK_FALSE,													// occlusionQueryEnable
1900		(VkQueryControlFlags)0u,									// queryFlags
1901		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
1902	};
1903	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
1904	{
1905		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1906		DE_NULL,
1907		0u,															// flags
1908		&secCmdBufInheritInfo,
1909	};
1910
1911	// Fill create info struct for event
1912	const VkEventCreateInfo					eventCreateInfo			=
1913	{
1914		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
1915		DE_NULL,
1916		0u,
1917	};
1918
1919	// create event that will be used to check if secondary command buffer has been executed
1920	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
1921
1922	// reset event
1923	VK_CHECK(vk.resetEvent(vkDevice, *event));
1924
1925	// record first primary command buffer
1926	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
1927	{
1928		// record secondary command buffer
1929		VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1930		{
1931			// allow execution of event during every stage of pipeline
1932			VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1933
1934			// record setting event
1935			vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1936		}
1937
1938		// end recording of secondary buffers
1939		VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
1940
1941		// execute secondary buffer
1942		vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
1943	}
1944	VK_CHECK(vk.endCommandBuffer(*primCmdBuf1));
1945
1946	const VkFenceCreateInfo					fenceCreateInfo			=
1947	{
1948		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1949		DE_NULL,
1950		0u,															// flags
1951	};
1952
1953	// create fence to wait for execution of queue
1954	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
1955
1956	const VkSubmitInfo						submitInfo1				=
1957	{
1958		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1959		DE_NULL,													// pNext
1960		0u,															// waitSemaphoreCount
1961		DE_NULL,													// pWaitSemaphores
1962		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1963		1,															// commandBufferCount
1964		&primCmdBuf1.get(),											// pCommandBuffers
1965		0u,															// signalSemaphoreCount
1966		DE_NULL,													// pSignalSemaphores
1967	};
1968
1969	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
1970
1971	// wait for end of execution of queue
1972	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1973	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
1974
1975	// check if secondary buffer has been executed
1976	VkResult result = vk.getEventStatus(vkDevice,*event);
1977	if (result != VK_EVENT_SET)
1978		return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
1979
1980	// reset first primary buffer
1981	vk.resetCommandBuffer( *primCmdBuf1, 0u);
1982
1983	// reset event to allow receiving it again
1984	VK_CHECK(vk.resetEvent(vkDevice, *event));
1985
1986	// record second primary command buffer
1987	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
1988	{
1989		// execute secondary buffer
1990		vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
1991	}
1992	// end recording
1993	VK_CHECK(vk.endCommandBuffer(*primCmdBuf2));
1994
1995	// submit second primary buffer, the secondary should be executed too
1996	const VkSubmitInfo						submitInfo2				=
1997	{
1998		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1999		DE_NULL,													// pNext
2000		0u,															// waitSemaphoreCount
2001		DE_NULL,													// pWaitSemaphores
2002		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2003		1,															// commandBufferCount
2004		&primCmdBuf2.get(),											// pCommandBuffers
2005		0u,															// signalSemaphoreCount
2006		DE_NULL,													// pSignalSemaphores
2007	};
2008	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
2009
2010	// wait for end of execution of queue
2011	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2012
2013	// check if secondary buffer has been executed
2014	result = vk.getEventStatus(vkDevice,*event);
2015	if (result != VK_EVENT_SET)
2016		return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
2017	else
2018		return tcu::TestStatus::pass("Submit Twice Secondary Command Buffer succeeded");
2019}
2020
2021tcu::TestStatus oneTimeSubmitFlagPrimaryBufferTest(Context& context)
2022{
2023
2024	const VkDevice							vkDevice				= context.getDevice();
2025	const DeviceInterface&					vk						= context.getDeviceInterface();
2026	const VkQueue							queue					= context.getUniversalQueue();
2027	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2028
2029	const VkCommandPoolCreateInfo			cmdPoolParams			=
2030	{
2031		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2032		DE_NULL,													//	const void*					pNext;
2033		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2034		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2035	};
2036	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2037
2038	// Command buffer
2039	const VkCommandBufferAllocateInfo		cmdBufParams			=
2040	{
2041		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
2042		DE_NULL,													//	const void*					pNext;
2043		*cmdPool,													//	VkCommandPool				pool;
2044		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2045		1u,															//	uint32_t					bufferCount;
2046	};
2047	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2048	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
2049	{
2050		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2051		DE_NULL,
2052		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,				// flags
2053		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2054	};
2055
2056	// Fill create info struct for event
2057	const VkEventCreateInfo					eventCreateInfo			=
2058	{
2059		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
2060		DE_NULL,
2061		0u,
2062	};
2063
2064	// create event that will be used to check if secondary command buffer has been executed
2065	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
2066
2067	// reset event
2068	VK_CHECK(vk.resetEvent(vkDevice, *event));
2069
2070	// record primary command buffer
2071	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
2072	{
2073		// allow execution of event during every stage of pipeline
2074		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2075
2076		// record setting event
2077		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
2078	}
2079	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
2080
2081	const VkFenceCreateInfo					fenceCreateInfo			=
2082	{
2083		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2084		DE_NULL,
2085		0u,															// flags
2086	};
2087
2088	// create fence to wait for execution of queue
2089	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
2090
2091	const VkSubmitInfo						submitInfo				=
2092	{
2093		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2094		DE_NULL,													// pNext
2095		0u,															// waitSemaphoreCount
2096		DE_NULL,													// pWaitSemaphores
2097		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2098		1,															// commandBufferCount
2099		&primCmdBuf.get(),											// pCommandBuffers
2100		0u,															// signalSemaphoreCount
2101		DE_NULL,													// pSignalSemaphores
2102	};
2103
2104	// submit primary buffer
2105	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2106
2107	// wait for end of execution of queue
2108	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2109	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
2110
2111	// check if buffer has been executed
2112	VkResult result = vk.getEventStatus(vkDevice,*event);
2113	if (result != VK_EVENT_SET)
2114		return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED");
2115
2116	// record primary command buffer again - implicit reset because of VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
2117	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
2118	{
2119		// allow execution of event during every stage of pipeline
2120		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2121
2122		// record setting event
2123		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
2124	}
2125	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
2126
2127	// reset event
2128	VK_CHECK(vk.resetEvent(vkDevice, *event));
2129
2130	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2131
2132	// wait for end of execution of queue
2133	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2134
2135	// check if buffer has been executed
2136	result = vk.getEventStatus(vkDevice,*event);
2137	if (result != VK_EVENT_SET)
2138		return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED");
2139	else
2140		return tcu::TestStatus::pass("oneTimeSubmitFlagPrimaryBufferTest succeeded");
2141}
2142
2143tcu::TestStatus oneTimeSubmitFlagSecondaryBufferTest(Context& context)
2144{
2145
2146	const VkDevice							vkDevice				= context.getDevice();
2147	const DeviceInterface&					vk						= context.getDeviceInterface();
2148	const VkQueue							queue					= context.getUniversalQueue();
2149	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2150
2151	const VkCommandPoolCreateInfo			cmdPoolParams			=
2152	{
2153		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2154		DE_NULL,													//	const void*					pNext;
2155		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2156		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2157	};
2158
2159	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2160
2161	// Command buffer
2162	const VkCommandBufferAllocateInfo		cmdBufParams			=
2163	{
2164		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2165		DE_NULL,													//	const void*				pNext;
2166		*cmdPool,													//	VkCommandPool				pool;
2167		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2168		1u,															//	uint32_t					bufferCount;
2169	};
2170
2171	const Unique<VkCommandBuffer>			primCmdBuf1				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2172	const Unique<VkCommandBuffer>			primCmdBuf2				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2173
2174	// Secondary Command buffer
2175	const VkCommandBufferAllocateInfo		secCmdBufParams			=
2176	{
2177		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2178		DE_NULL,													//	const void*				pNext;
2179		*cmdPool,													//	VkCommandPool				pool;
2180		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2181		1u,															//	uint32_t					bufferCount;
2182	};
2183	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2184
2185	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
2186	{
2187		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2188		DE_NULL,
2189		0,															// flags
2190		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2191	};
2192
2193	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
2194	{
2195		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2196		DE_NULL,
2197		(VkRenderPass)0u,											// renderPass
2198		0u,															// subpass
2199		(VkFramebuffer)0u,											// framebuffer
2200		VK_FALSE,													// occlusionQueryEnable
2201		(VkQueryControlFlags)0u,									// queryFlags
2202		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2203	};
2204	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
2205	{
2206		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2207		DE_NULL,
2208		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,				// flags
2209		&secCmdBufInheritInfo,
2210	};
2211
2212	// Fill create info struct for event
2213	const VkEventCreateInfo					eventCreateInfo			=
2214	{
2215		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
2216		DE_NULL,
2217		0u,
2218	};
2219
2220	// create event that will be used to check if secondary command buffer has been executed
2221	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
2222
2223	// reset event
2224	VK_CHECK(vk.resetEvent(vkDevice, *event));
2225
2226	// record first primary command buffer
2227	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
2228	{
2229		// record secondary command buffer
2230		VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2231		{
2232			// allow execution of event during every stage of pipeline
2233			VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2234
2235			// record setting event
2236			vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
2237		}
2238
2239		// end recording of secondary buffers
2240		VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
2241
2242		// execute secondary buffer
2243		vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
2244	}
2245	VK_CHECK(vk.endCommandBuffer(*primCmdBuf1));
2246
2247	const VkFenceCreateInfo					fenceCreateInfo			=
2248	{
2249		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2250		DE_NULL,
2251		0u,															// flags
2252	};
2253
2254	// create fence to wait for execution of queue
2255	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
2256
2257	const VkSubmitInfo						submitInfo1				=
2258	{
2259		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2260		DE_NULL,													// pNext
2261		0u,															// waitSemaphoreCount
2262		DE_NULL,													// pWaitSemaphores
2263		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2264		1,															// commandBufferCount
2265		&primCmdBuf1.get(),											// pCommandBuffers
2266		0u,															// signalSemaphoreCount
2267		DE_NULL,													// pSignalSemaphores
2268	};
2269
2270	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
2271
2272	// wait for end of execution of queue
2273	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2274	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
2275
2276	// check if secondary buffer has been executed
2277	VkResult result = vk.getEventStatus(vkDevice,*event);
2278	if (result != VK_EVENT_SET)
2279		return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
2280
2281	// reset first primary buffer
2282	vk.resetCommandBuffer( *primCmdBuf1, 0u);
2283
2284	// reset event to allow receiving it again
2285	VK_CHECK(vk.resetEvent(vkDevice, *event));
2286
2287	// record secondary command buffer again
2288	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2289	{
2290		// allow execution of event during every stage of pipeline
2291		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2292
2293		// record setting event
2294		vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
2295	}
2296	// end recording of secondary buffers
2297	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
2298
2299	// record second primary command buffer
2300	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
2301	{
2302		// execute secondary buffer
2303		vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
2304	}
2305	// end recording
2306	VK_CHECK(vk.endCommandBuffer(*primCmdBuf2));
2307
2308	// submit second primary buffer, the secondary should be executed too
2309	const VkSubmitInfo						submitInfo2				=
2310	{
2311		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2312		DE_NULL,													// pNext
2313		0u,															// waitSemaphoreCount
2314		DE_NULL,													// pWaitSemaphores
2315		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2316		1,															// commandBufferCount
2317		&primCmdBuf2.get(),											// pCommandBuffers
2318		0u,															// signalSemaphoreCount
2319		DE_NULL,													// pSignalSemaphores
2320	};
2321	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
2322
2323	// wait for end of execution of queue
2324	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2325
2326	// check if secondary buffer has been executed
2327	result = vk.getEventStatus(vkDevice,*event);
2328	if (result != VK_EVENT_SET)
2329		return tcu::TestStatus::fail("oneTimeSubmitFlagSecondaryBufferTest FAILED");
2330	else
2331		return tcu::TestStatus::pass("oneTimeSubmitFlagSecondaryBufferTest succeeded");
2332}
2333
2334tcu::TestStatus renderPassContinueTest(Context& context)
2335{
2336	const DeviceInterface&					vkd						= context.getDeviceInterface();
2337	CommandBufferRenderPassTestEnvironment	env						(context, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
2338
2339	VkCommandBuffer							primaryCommandBuffer	= env.getPrimaryCommandBuffer();
2340	VkCommandBuffer							secondaryCommandBuffer	= env.getSecondaryCommandBuffer();
2341	const deUint32							clearColor[4]			= { 2, 47, 131, 211 };
2342
2343	const VkClearAttachment					clearAttachment			=
2344	{
2345		VK_IMAGE_ASPECT_COLOR_BIT,									// VkImageAspectFlags	aspectMask;
2346		0,															// deUint32				colorAttachment;
2347		makeClearValueColorU32(clearColor[0],
2348							   clearColor[1],
2349							   clearColor[2],
2350							   clearColor[3])						// VkClearValue			clearValue;
2351	};
2352
2353	const VkClearRect						clearRect				=
2354	{
2355		CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA,	// VkRect2D	rect;
2356		0u,															// deUint32	baseArrayLayer;
2357		1u															// deUint32	layerCount;
2358	};
2359
2360	env.beginSecondaryCommandBuffer(VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2361	vkd.cmdClearAttachments(secondaryCommandBuffer, 1, &clearAttachment, 1, &clearRect);
2362	VK_CHECK(vkd.endCommandBuffer(secondaryCommandBuffer));
2363
2364
2365	env.beginPrimaryCommandBuffer(0);
2366	env.beginRenderPass(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2367	vkd.cmdExecuteCommands(primaryCommandBuffer, 1, &secondaryCommandBuffer);
2368	vkd.cmdEndRenderPass(primaryCommandBuffer);
2369
2370	VK_CHECK(vkd.endCommandBuffer(primaryCommandBuffer));
2371
2372	env.submitPrimaryCommandBuffer();
2373
2374	de::MovePtr<tcu::TextureLevel>			result					= env.readColorAttachment();
2375	tcu::PixelBufferAccess					pixelBufferAccess		= result->getAccess();
2376
2377	for (deUint32 i = 0; i < (CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.width * CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.height); ++i)
2378	{
2379		deUint8* colorData = reinterpret_cast<deUint8*>(pixelBufferAccess.getDataPtr());
2380		for (int colorComponent = 0; colorComponent < 4; ++colorComponent)
2381			if (colorData[i * 4 + colorComponent] != clearColor[colorComponent])
2382				return tcu::TestStatus::fail("clear value mismatch");
2383	}
2384
2385	return tcu::TestStatus::pass("render pass continue test passed");
2386}
2387
2388tcu::TestStatus simultaneousUsePrimaryBufferTest(Context& context)
2389{
2390
2391	const VkDevice							vkDevice				= context.getDevice();
2392	const DeviceInterface&					vk						= context.getDeviceInterface();
2393	const VkQueue							queue					= context.getUniversalQueue();
2394	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2395
2396	const VkCommandPoolCreateInfo			cmdPoolParams			=
2397	{
2398		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2399		DE_NULL,													//	const void*					pNext;
2400		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2401		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2402	};
2403	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2404
2405	// Command buffer
2406	const VkCommandBufferAllocateInfo		cmdBufParams			=
2407	{
2408		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
2409		DE_NULL,													//	const void*					pNext;
2410		*cmdPool,													//	VkCommandPool				pool;
2411		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2412		1u,															//	uint32_t					bufferCount;
2413	};
2414	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2415	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
2416	{
2417		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2418		DE_NULL,
2419		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2420		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2421	};
2422
2423	// Fill create info struct for event
2424	const VkEventCreateInfo					eventCreateInfo			=
2425	{
2426		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
2427		DE_NULL,
2428		0u,
2429	};
2430
2431	// create event that will be used to check if secondary command buffer has been executed
2432	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice, &eventCreateInfo));
2433	const Unique<VkEvent>					eventTwo				(createEvent(vk, vkDevice, &eventCreateInfo));
2434
2435	// reset event
2436	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
2437
2438	// record primary command buffer
2439	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
2440	{
2441		// wait for event
2442		vk.cmdWaitEvents(*primCmdBuf, 1u, &eventOne.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
2443
2444		// Set the second event
2445		vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2446	}
2447	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
2448
2449	const VkFenceCreateInfo					fenceCreateInfo			=
2450	{
2451		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2452		DE_NULL,
2453		0u,															// flags
2454	};
2455
2456	// create fence to wait for execution of queue
2457	const Unique<VkFence>					fence1					(createFence(vk, vkDevice, &fenceCreateInfo));
2458	const Unique<VkFence>					fence2					(createFence(vk, vkDevice, &fenceCreateInfo));
2459
2460
2461	const VkSubmitInfo						submitInfo				=
2462	{
2463		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2464		DE_NULL,													// pNext
2465		0u,															// waitSemaphoreCount
2466		DE_NULL,													// pWaitSemaphores
2467		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2468		1,															// commandBufferCount
2469		&primCmdBuf.get(),											// pCommandBuffers
2470		0u,															// signalSemaphoreCount
2471		DE_NULL,													// pSignalSemaphores
2472	};
2473
2474	// submit first buffer
2475	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence1));
2476
2477	// submit second buffer
2478	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence2));
2479
2480	// wait for both buffer to stop at event for 100 microseconds
2481	vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, 100000);
2482	vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, 100000);
2483
2484	// set event
2485	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
2486
2487	// wait for end of execution of the first buffer
2488	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, INFINITE_TIMEOUT));
2489	// wait for end of execution of the second buffer
2490	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, INFINITE_TIMEOUT));
2491
2492	// TODO: this will be true if the command buffer was executed only once
2493	// TODO: add some test that will say if it was executed twice
2494
2495	// check if buffer has been executed
2496	VkResult result = vk.getEventStatus(vkDevice, *eventTwo);
2497	if (result == VK_EVENT_SET)
2498		return tcu::TestStatus::pass("simultaneous use - primary buffers test succeeded");
2499	else
2500		return tcu::TestStatus::fail("simultaneous use - primary buffers test FAILED");
2501}
2502
2503tcu::TestStatus simultaneousUseSecondaryBufferTest(Context& context)
2504{
2505	const VkDevice							vkDevice				= context.getDevice();
2506	const DeviceInterface&					vk						= context.getDeviceInterface();
2507	const VkQueue							queue					= context.getUniversalQueue();
2508	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2509
2510	const VkCommandPoolCreateInfo			cmdPoolParams			=
2511	{
2512		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2513		DE_NULL,													//	const void*					pNext;
2514		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2515		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2516	};
2517	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2518
2519	// Command buffer
2520	const VkCommandBufferAllocateInfo		cmdBufParams			=
2521	{
2522		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2523		DE_NULL,													//	const void*				pNext;
2524		*cmdPool,													//	VkCommandPool				pool;
2525		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2526		1u,															//	uint32_t					bufferCount;
2527	};
2528	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2529
2530	// Secondary Command buffer params
2531	const VkCommandBufferAllocateInfo		secCmdBufParams			=
2532	{
2533		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2534		DE_NULL,													//	const void*				pNext;
2535		*cmdPool,													//	VkCommandPool				pool;
2536		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2537		1u,															//	uint32_t					bufferCount;
2538	};
2539	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2540
2541	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
2542	{
2543		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2544		DE_NULL,
2545		0,															// flags
2546		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2547	};
2548
2549	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
2550	{
2551		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2552		DE_NULL,
2553		(VkRenderPass)0u,											// renderPass
2554		0u,															// subpass
2555		(VkFramebuffer)0u,											// framebuffer
2556		VK_FALSE,													// occlusionQueryEnable
2557		(VkQueryControlFlags)0u,									// queryFlags
2558		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2559	};
2560	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
2561	{
2562		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2563		DE_NULL,
2564		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2565		&secCmdBufInheritInfo,
2566	};
2567
2568	// Fill create info struct for event
2569	const VkEventCreateInfo					eventCreateInfo			=
2570	{
2571		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
2572		DE_NULL,
2573		0u,
2574	};
2575
2576	// create event that will be used to check if secondary command buffer has been executed
2577	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice, &eventCreateInfo));
2578	const Unique<VkEvent>					eventTwo				(createEvent(vk, vkDevice, &eventCreateInfo));
2579
2580	// reset event
2581	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
2582	VK_CHECK(vk.resetEvent(vkDevice, *eventTwo));
2583
2584	// record secondary command buffer
2585	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2586	{
2587		// allow execution of event during every stage of pipeline
2588		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2589
2590		// wait for event
2591		vk.cmdWaitEvents(*secCmdBuf, 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
2592
2593		// reset event
2594		vk.cmdSetEvent(*secCmdBuf, *eventTwo, stageMask);
2595	}
2596	// end recording of secondary buffers
2597	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
2598
2599	// record primary command buffer
2600	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
2601	{
2602		// execute secondary buffer
2603		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2604	}
2605	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
2606
2607	const VkFenceCreateInfo					fenceCreateInfo			=
2608	{
2609		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2610		DE_NULL,
2611		0u,															// flags
2612	};
2613
2614	// create fence to wait for execution of queue
2615	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
2616
2617	const VkSubmitInfo						submitInfo				=
2618	{
2619		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2620		DE_NULL,													// pNext
2621		0u,															// waitSemaphoreCount
2622		DE_NULL,													// pWaitSemaphores
2623		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2624		1,															// commandBufferCount
2625		&primCmdBuf.get(),											// pCommandBuffers
2626		0u,															// signalSemaphoreCount
2627		DE_NULL,													// pSignalSemaphores
2628	};
2629
2630	// submit primary buffer, the secondary should be executed too
2631	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2632
2633	// wait for both buffers to stop at event for 100 microseconds
2634	vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 100000);
2635
2636	// set event
2637	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
2638
2639	// wait for end of execution of queue
2640	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2641
2642	// TODO: this will be true if the command buffer was executed only once
2643	// TODO: add some test that will say if it was executed twice
2644
2645	// check if secondary buffer has been executed
2646	VkResult result = vk.getEventStatus(vkDevice,*eventTwo);
2647	if (result == VK_EVENT_SET)
2648		return tcu::TestStatus::pass("Simulatous Secondary Command Buffer Execution succeeded");
2649	else
2650		return tcu::TestStatus::fail("Simulatous Secondary Command Buffer Execution FAILED");
2651}
2652
2653tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& context)
2654{
2655	const VkDevice							vkDevice = context.getDevice();
2656	const DeviceInterface&					vk = context.getDeviceInterface();
2657	const VkQueue							queue = context.getUniversalQueue();
2658	const deUint32							queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2659	Allocator&								allocator = context.getDefaultAllocator();
2660	const ComputeInstanceResultBuffer		result(vk, vkDevice, allocator, 0.0f);
2661
2662	const VkCommandPoolCreateInfo			cmdPoolParams =
2663	{
2664		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2665		DE_NULL,													//	const void*					pNext;
2666		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2667		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2668	};
2669	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2670
2671	// Command buffer
2672	const VkCommandBufferAllocateInfo		cmdBufParams =
2673	{
2674		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2675		DE_NULL,													//	const void*				pNext;
2676		*cmdPool,													//	VkCommandPool				pool;
2677		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2678		1u,															//	uint32_t					bufferCount;
2679	};
2680	const Unique<VkCommandBuffer>			primCmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2681
2682	// Secondary Command buffer params
2683	const VkCommandBufferAllocateInfo		secCmdBufParams =
2684	{
2685		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2686		DE_NULL,													//	const void*				pNext;
2687		*cmdPool,													//	VkCommandPool				pool;
2688		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2689		1u,															//	uint32_t					bufferCount;
2690	};
2691	const Unique<VkCommandBuffer>			secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2692
2693	const VkCommandBufferBeginInfo			primCmdBufBeginInfo =
2694	{
2695		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2696		DE_NULL,
2697		0,															// flags
2698		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2699	};
2700
2701	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo =
2702	{
2703		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2704		DE_NULL,
2705		(VkRenderPass)0u,
2706		0u,															// subpass
2707		(VkFramebuffer)0u,
2708		VK_FALSE,													// occlusionQueryEnable
2709		(VkQueryControlFlags)0u,
2710		(VkQueryPipelineStatisticFlags)0u,
2711	};
2712	const VkCommandBufferBeginInfo			secCmdBufBeginInfo =
2713	{
2714		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2715		DE_NULL,
2716		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2717		&secCmdBufInheritInfo,
2718	};
2719
2720	const deUint32							offset = (0u);
2721	const deUint32							addressableSize = 256;
2722	const deUint32							dataSize = 8;
2723	de::MovePtr<Allocation>					bufferMem;
2724	const Unique<VkBuffer>					buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2725	// Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2726	const Unique<VkDescriptorSetLayout>		descriptorSetLayout(createDescriptorSetLayout(context));
2727	const Unique<VkDescriptorPool>			descriptorPool(createDescriptorPool(context));
2728	const Unique<VkDescriptorSet>			descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2729	const VkDescriptorSet					descriptorSets[] = { *descriptorSet };
2730	const int								numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2731
2732	const VkPipelineLayoutCreateInfo layoutCreateInfo =
2733	{
2734		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
2735		DE_NULL,													// pNext
2736		(VkPipelineLayoutCreateFlags)0,
2737		numDescriptorSets,											// setLayoutCount
2738		&descriptorSetLayout.get(),									// pSetLayouts
2739		0u,															// pushConstantRangeCount
2740		DE_NULL,													// pPushConstantRanges
2741	};
2742	Unique<VkPipelineLayout>				pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2743
2744	const Unique<VkShaderModule>			computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2745
2746	const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
2747	{
2748		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2749		DE_NULL,
2750		(VkPipelineShaderStageCreateFlags)0,
2751		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
2752		*computeModule,												// shader
2753		"main",
2754		DE_NULL,													// pSpecializationInfo
2755	};
2756
2757	const VkComputePipelineCreateInfo		pipelineCreateInfo =
2758	{
2759		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2760		DE_NULL,
2761		0u,															// flags
2762		shaderCreateInfo,											// cs
2763		*pipelineLayout,											// layout
2764		(vk::VkPipeline)0,											// basePipelineHandle
2765		0u,															// basePipelineIndex
2766	};
2767
2768	const Unique<VkPipeline>				pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2769
2770	// record secondary command buffer
2771	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2772	{
2773		vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2774		vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2775		vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2776	}
2777	// end recording of secondary buffer
2778	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
2779
2780	// record primary command buffer
2781	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
2782	{
2783		// execute secondary buffer twice in same primary
2784		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2785		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2786	}
2787	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
2788
2789	const VkFenceCreateInfo					fenceCreateInfo =
2790	{
2791		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2792		DE_NULL,
2793		0u,															// flags
2794	};
2795
2796	// create fence to wait for execution of queue
2797	const Unique<VkFence>					fence(createFence(vk, vkDevice, &fenceCreateInfo));
2798
2799	const VkSubmitInfo						submitInfo =
2800	{
2801		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2802		DE_NULL,													// pNext
2803		0u,															// waitSemaphoreCount
2804		DE_NULL,													// pWaitSemaphores
2805		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2806		1,															// commandBufferCount
2807		&primCmdBuf.get(),											// pCommandBuffers
2808		0u,															// signalSemaphoreCount
2809		DE_NULL,													// pSignalSemaphores
2810	};
2811
2812	// submit primary buffer, the secondary should be executed too
2813	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2814
2815	// wait for end of execution of queue
2816	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2817
2818	deUint32 resultCount;
2819	result.readResultContentsTo(&resultCount);
2820	// check if secondary buffer has been executed
2821	if (resultCount == 2)
2822		return tcu::TestStatus::pass("Simulatous Secondary Command Buffer Execution succeeded");
2823	else
2824		return tcu::TestStatus::fail("Simulatous Secondary Command Buffer Execution FAILED");
2825}
2826
2827tcu::TestStatus simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context& context)
2828{
2829	const VkDevice							vkDevice = context.getDevice();
2830	const DeviceInterface&					vk = context.getDeviceInterface();
2831	const VkQueue							queue = context.getUniversalQueue();
2832	const deUint32							queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2833	Allocator&								allocator = context.getDefaultAllocator();
2834	const ComputeInstanceResultBuffer		result(vk, vkDevice, allocator, 0.0f);
2835
2836	const VkCommandPoolCreateInfo			cmdPoolParams =
2837	{
2838		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2839		DE_NULL,													//	const void*					pNext;
2840		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2841		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2842	};
2843	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2844
2845	// Command buffer
2846	const VkCommandBufferAllocateInfo		cmdBufParams =
2847	{
2848		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2849		DE_NULL,													//	const void*				pNext;
2850		*cmdPool,													//	VkCommandPool				pool;
2851		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2852		1u,															//	uint32_t					bufferCount;
2853	};
2854	// Two separate primary cmd buffers that will be executed with the same secondary cmd buffer
2855	const deUint32 numPrimCmdBufs = 2;
2856	const Unique<VkCommandBuffer>			primCmdBufOne(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2857	const Unique<VkCommandBuffer>			primCmdBufTwo(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2858	VkCommandBuffer primCmdBufs[numPrimCmdBufs];
2859	primCmdBufs[0] = primCmdBufOne.get();
2860	primCmdBufs[1] = primCmdBufTwo.get();
2861
2862	// Secondary Command buffer params
2863	const VkCommandBufferAllocateInfo		secCmdBufParams =
2864	{
2865		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2866		DE_NULL,													//	const void*				pNext;
2867		*cmdPool,													//	VkCommandPool				pool;
2868		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2869		1u,															//	uint32_t					bufferCount;
2870	};
2871	const Unique<VkCommandBuffer>			secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2872
2873	const VkCommandBufferBeginInfo			primCmdBufBeginInfo =
2874	{
2875		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2876		DE_NULL,
2877		0,															// flags
2878		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2879	};
2880
2881	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo =
2882	{
2883		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2884		DE_NULL,
2885		(VkRenderPass)0u,											// renderPass
2886		0u,															// subpass
2887		(VkFramebuffer)0u,											// framebuffer
2888		VK_FALSE,													// occlusionQueryEnable
2889		(VkQueryControlFlags)0u,									// queryFlags
2890		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2891	};
2892	const VkCommandBufferBeginInfo			secCmdBufBeginInfo =
2893	{
2894		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2895		DE_NULL,
2896		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2897		&secCmdBufInheritInfo,
2898	};
2899
2900	const deUint32							offset = (0u);
2901	const deUint32							addressableSize = 256;
2902	const deUint32							dataSize = 8;
2903	de::MovePtr<Allocation>					bufferMem;
2904	const Unique<VkBuffer>					buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2905	// Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2906	const Unique<VkDescriptorSetLayout>		descriptorSetLayout(createDescriptorSetLayout(context));
2907	const Unique<VkDescriptorPool>			descriptorPool(createDescriptorPool(context));
2908	const Unique<VkDescriptorSet>			descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2909	const VkDescriptorSet					descriptorSets[] = { *descriptorSet };
2910	const int								numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2911
2912	const VkPipelineLayoutCreateInfo layoutCreateInfo =
2913	{
2914		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
2915		DE_NULL,													// pNext
2916		(VkPipelineLayoutCreateFlags)0,
2917		numDescriptorSets,											// setLayoutCount
2918		&descriptorSetLayout.get(),									// pSetLayouts
2919		0u,															// pushConstantRangeCount
2920		DE_NULL,													// pPushConstantRanges
2921	};
2922	Unique<VkPipelineLayout>				pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2923
2924	const Unique<VkShaderModule>			computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2925
2926	const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
2927	{
2928		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2929		DE_NULL,
2930		(VkPipelineShaderStageCreateFlags)0,
2931		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
2932		*computeModule,												// shader
2933		"main",
2934		DE_NULL,													// pSpecializationInfo
2935	};
2936
2937	const VkComputePipelineCreateInfo		pipelineCreateInfo =
2938	{
2939		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2940		DE_NULL,
2941		0u,															// flags
2942		shaderCreateInfo,											// cs
2943		*pipelineLayout,											// layout
2944		(vk::VkPipeline)0,											// basePipelineHandle
2945		0u,															// basePipelineIndex
2946	};
2947
2948	const Unique<VkPipeline>				pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2949
2950	// record secondary command buffer
2951	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2952	{
2953		vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2954		vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2955		vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2956	}
2957	// end recording of secondary buffer
2958	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
2959
2960	// record primary command buffers
2961	// Insert one instance of same secondary command buffer into two separate primary command buffers
2962	VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
2963	{
2964		vk.cmdExecuteCommands(*primCmdBufOne, 1, &secCmdBuf.get());
2965	}
2966	VK_CHECK(vk.endCommandBuffer(*primCmdBufOne));
2967
2968	VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
2969	{
2970		vk.cmdExecuteCommands(*primCmdBufTwo, 1, &secCmdBuf.get());
2971	}
2972	VK_CHECK(vk.endCommandBuffer(*primCmdBufTwo));
2973
2974	const VkFenceCreateInfo					fenceCreateInfo =
2975	{
2976		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2977		DE_NULL,
2978		0u,															// flags
2979	};
2980
2981	// create fence to wait for execution of queue
2982	const Unique<VkFence>					fence(createFence(vk, vkDevice, &fenceCreateInfo));
2983
2984	const VkSubmitInfo						submitInfo =
2985	{
2986		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2987		DE_NULL,													// pNext
2988		0u,															// waitSemaphoreCount
2989		DE_NULL,													// pWaitSemaphores
2990		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2991		numPrimCmdBufs,												// commandBufferCount
2992		primCmdBufs,												// pCommandBuffers
2993		0u,															// signalSemaphoreCount
2994		DE_NULL,													// pSignalSemaphores
2995	};
2996
2997	// submit primary buffers, the secondary should be executed too
2998	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2999
3000	// wait for end of execution of queue
3001	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3002
3003	deUint32 resultCount;
3004	result.readResultContentsTo(&resultCount);
3005	// check if secondary buffer has been executed
3006	if (resultCount == 2)
3007		return tcu::TestStatus::pass("Simulatous Secondary Command Buffer Execution succeeded");
3008	else
3009		return tcu::TestStatus::fail("Simulatous Secondary Command Buffer Execution FAILED");
3010}
3011
3012tcu::TestStatus recordBufferQueryPreciseWithFlagTest(Context& context)
3013{
3014	const VkDevice							vkDevice				= context.getDevice();
3015	const DeviceInterface&					vk						= context.getDeviceInterface();
3016	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3017
3018	if (!context.getDeviceFeatures().inheritedQueries)
3019		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
3020
3021	const VkCommandPoolCreateInfo			cmdPoolParams			=
3022	{
3023		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3024		DE_NULL,													// pNext;
3025		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
3026		queueFamilyIndex,											// queueFamilyIndex;
3027	};
3028	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3029
3030	// Command buffer
3031	const VkCommandBufferAllocateInfo		primCmdBufParams		=
3032	{
3033		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3034		DE_NULL,													// pNext;
3035		*cmdPool,													// pool;
3036		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3037		1u,															// flags;
3038	};
3039	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
3040
3041	// Secondary Command buffer params
3042	const VkCommandBufferAllocateInfo		secCmdBufParams			=
3043	{
3044		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3045		DE_NULL,													// pNext;
3046		*cmdPool,													// pool;
3047		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
3048		1u,															// flags;
3049	};
3050	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3051
3052	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
3053	{
3054		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3055		DE_NULL,													// pNext
3056		0u,															// flags
3057		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3058	};
3059
3060	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
3061	{
3062		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3063		DE_NULL,
3064		0u,															// renderPass
3065		0u,															// subpass
3066		0u,															// framebuffer
3067		VK_TRUE,													// occlusionQueryEnable
3068		VK_QUERY_CONTROL_PRECISE_BIT,								// queryFlags
3069		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
3070	};
3071	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
3072	{
3073		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3074		DE_NULL,													// pNext
3075		0u,															// flags
3076		&secBufferInheritInfo,
3077	};
3078
3079	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
3080	{
3081		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
3082		DE_NULL,													// pNext
3083		(VkQueryPoolCreateFlags)0,									// flags
3084		VK_QUERY_TYPE_OCCLUSION,									// queryType
3085		1u,															// entryCount
3086		0u,															// pipelineStatistics
3087	};
3088	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
3089
3090	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
3091	VK_CHECK(vk.endCommandBuffer(secCmdBuf.get()));
3092
3093	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
3094	{
3095		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
3096		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
3097		{
3098			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
3099		}
3100		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
3101	}
3102	VK_CHECK(vk.endCommandBuffer(primCmdBuf.get()));
3103
3104	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
3105}
3106
3107tcu::TestStatus recordBufferQueryImpreciseWithFlagTest(Context& context)
3108{
3109	const VkDevice							vkDevice				= context.getDevice();
3110	const DeviceInterface&					vk						= context.getDeviceInterface();
3111	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3112
3113	if (!context.getDeviceFeatures().inheritedQueries)
3114		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
3115
3116	const VkCommandPoolCreateInfo			cmdPoolParams			=
3117	{
3118		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3119		DE_NULL,													// pNext;
3120		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
3121		queueFamilyIndex,											// queueFamilyIndex;
3122	};
3123	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3124
3125	// Command buffer
3126	const VkCommandBufferAllocateInfo		primCmdBufParams		=
3127	{
3128		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3129		DE_NULL,													// pNext;
3130		*cmdPool,													// pool;
3131		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3132		1u,															// flags;
3133	};
3134	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
3135
3136	// Secondary Command buffer params
3137	const VkCommandBufferAllocateInfo		secCmdBufParams			=
3138	{
3139		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3140		DE_NULL,													// pNext;
3141		*cmdPool,													// pool;
3142		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
3143		1u,															// flags;
3144	};
3145	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3146
3147	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
3148	{
3149		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3150		DE_NULL,													// pNext
3151		0u,															// flags
3152		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3153	};
3154
3155	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
3156	{
3157		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3158		DE_NULL,
3159		0u,															// renderPass
3160		0u,															// subpass
3161		0u,															// framebuffer
3162		VK_TRUE,													// occlusionQueryEnable
3163		VK_QUERY_CONTROL_PRECISE_BIT,								// queryFlags
3164		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
3165	};
3166	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
3167	{
3168		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3169		DE_NULL,													// pNext
3170		0u,															// flags
3171		&secBufferInheritInfo,
3172	};
3173
3174	// Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
3175	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
3176	{
3177		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
3178		DE_NULL,													// pNext
3179		0u,															// flags
3180		VK_QUERY_TYPE_OCCLUSION,									// queryType
3181		1u,															// entryCount
3182		0u,															// pipelineStatistics
3183	};
3184	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
3185
3186	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
3187	VK_CHECK(vk.endCommandBuffer(secCmdBuf.get()));
3188
3189	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
3190	{
3191		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
3192		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
3193		{
3194			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
3195		}
3196		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
3197	}
3198	VK_CHECK(vk.endCommandBuffer(primCmdBuf.get()));
3199
3200	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
3201}
3202
3203tcu::TestStatus recordBufferQueryImpreciseWithoutFlagTest(Context& context)
3204{
3205	const VkDevice							vkDevice				= context.getDevice();
3206	const DeviceInterface&					vk						= context.getDeviceInterface();
3207	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3208
3209	if (!context.getDeviceFeatures().inheritedQueries)
3210		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
3211
3212	const VkCommandPoolCreateInfo			cmdPoolParams			=
3213	{
3214		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3215		DE_NULL,													// pNext;
3216		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
3217		queueFamilyIndex,											// queueFamilyIndex;
3218	};
3219	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3220
3221	// Command buffer
3222	const VkCommandBufferAllocateInfo		primCmdBufParams		=
3223	{
3224		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3225		DE_NULL,													// pNext;
3226		*cmdPool,													// pool;
3227		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3228		1u,															// flags;
3229	};
3230	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
3231
3232	// Secondary Command buffer params
3233	const VkCommandBufferAllocateInfo		secCmdBufParams			=
3234	{
3235		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3236		DE_NULL,													// pNext;
3237		*cmdPool,													// pool;
3238		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
3239		1u,															// flags;
3240	};
3241	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3242
3243	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
3244	{
3245		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3246		DE_NULL,													// pNext
3247		0u,															// flags
3248		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3249	};
3250
3251	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
3252	{
3253		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3254		DE_NULL,
3255		0u,															// renderPass
3256		0u,															// subpass
3257		0u,															// framebuffer
3258		VK_TRUE,													// occlusionQueryEnable
3259		0u,															// queryFlags
3260		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
3261	};
3262	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
3263	{
3264		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3265		DE_NULL,													// pNext
3266		0u,															// flags
3267		&secBufferInheritInfo,
3268	};
3269
3270	// Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
3271	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
3272	{
3273		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
3274		DE_NULL,													// pNext
3275		(VkQueryPoolCreateFlags)0,
3276		VK_QUERY_TYPE_OCCLUSION,
3277		1u,
3278		0u,
3279	};
3280	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
3281
3282	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
3283	VK_CHECK(vk.endCommandBuffer(secCmdBuf.get()));
3284
3285	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
3286	{
3287		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
3288		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
3289		{
3290			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
3291		}
3292		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
3293	}
3294	VK_CHECK(vk.endCommandBuffer(primCmdBuf.get()));
3295
3296	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
3297}
3298
3299/******** 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) ****************/
3300tcu::TestStatus submitBufferCountNonZero(Context& context)
3301{
3302	const VkDevice							vkDevice				= context.getDevice();
3303	const DeviceInterface&					vk						= context.getDeviceInterface();
3304	const VkQueue							queue					= context.getUniversalQueue();
3305	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3306
3307	const deUint32							BUFFER_COUNT			= 5u;
3308
3309	const VkCommandPoolCreateInfo			cmdPoolParams			=
3310	{
3311		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3312		DE_NULL,													// pNext;
3313		0u,															// flags;
3314		queueFamilyIndex,											// queueFamilyIndex;
3315	};
3316	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3317
3318	// Command buffer
3319	const VkCommandBufferAllocateInfo		cmdBufParams			=
3320	{
3321		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3322		DE_NULL,													// pNext;
3323		*cmdPool,													// pool;
3324		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3325		BUFFER_COUNT,												// bufferCount;
3326	};
3327	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3328	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
3329
3330	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3331	{
3332		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3333		DE_NULL,													// pNext
3334		0u,															// flags
3335		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3336	};
3337
3338	const VkEventCreateInfo					eventCreateInfo			=
3339	{
3340		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,						// sType;
3341		DE_NULL,													// pNext;
3342		0u,															// flags;
3343	};
3344
3345	std::vector<VkEventSp>					events;
3346	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3347	{
3348		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL))));
3349	}
3350
3351	// Record the command buffers
3352	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3353	{
3354		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3355		{
3356			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3357		}
3358		VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3359	}
3360
3361	// We'll use a fence to wait for the execution of the queue
3362	const VkFenceCreateInfo					fenceCreateInfo			=
3363	{
3364		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,						// sType;
3365		DE_NULL,													// pNext;
3366		0u,															// flags
3367	};
3368	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
3369
3370	const VkSubmitInfo						submitInfo				=
3371	{
3372		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3373		DE_NULL,													// pNext
3374		0u,															// waitSemaphoreCount
3375		DE_NULL,													// pWaitSemaphores
3376		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3377		BUFFER_COUNT,												// commandBufferCount
3378		cmdBuffers,													// pCommandBuffers
3379		0u,															// signalSemaphoreCount
3380		DE_NULL,													// pSignalSemaphores
3381	};
3382
3383	// Submit the alpha command buffer to the queue
3384	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
3385	// Wait for the queue
3386	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3387
3388	// Check if the buffers were executed
3389	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3390
3391	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3392	{
3393		if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
3394		{
3395			testResult = tcu::TestStatus::fail("Failed to set the event.");
3396			break;
3397		}
3398	}
3399
3400	if (!testResult.isComplete())
3401		testResult = tcu::TestStatus::pass("All buffers were submitted and executed correctly.");
3402
3403	return testResult;
3404}
3405
3406tcu::TestStatus submitBufferCountEqualZero(Context& context)
3407{
3408	const VkDevice							vkDevice				= context.getDevice();
3409	const DeviceInterface&					vk						= context.getDeviceInterface();
3410	const VkQueue							queue					= context.getUniversalQueue();
3411	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3412
3413	const deUint32							BUFFER_COUNT			= 2u;
3414
3415	const VkCommandPoolCreateInfo			cmdPoolParams			=
3416	{
3417		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3418		DE_NULL,													// pNext;
3419		0u,															// flags;
3420		queueFamilyIndex,											// queueFamilyIndex;
3421	};
3422	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3423
3424	// Command buffer
3425	const VkCommandBufferAllocateInfo		cmdBufParams			=
3426	{
3427		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3428		DE_NULL,													// pNext;
3429		*cmdPool,													// pool;
3430		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3431		BUFFER_COUNT,												// bufferCount;
3432	};
3433	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3434	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
3435
3436	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3437	{
3438		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3439		DE_NULL,													// pNext
3440		0u,															// flags
3441		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3442	};
3443
3444	const VkEventCreateInfo					eventCreateInfo			=
3445	{
3446		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,						// sType;
3447		DE_NULL,													// pNext;
3448		0u,															// flags;
3449	};
3450
3451	std::vector<VkEventSp>					events;
3452	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3453		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL))));
3454
3455	// Record the command buffers
3456	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3457	{
3458		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3459		{
3460			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3461		}
3462		VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3463	}
3464
3465	// We'll use a fence to wait for the execution of the queue
3466	const VkFenceCreateInfo					fenceCreateInfo			=
3467	{
3468		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,						// sType;
3469		DE_NULL,													// pNext;
3470		0u,															// flags
3471	};
3472	const Unique<VkFence>					fenceZero				(createFence(vk, vkDevice, &fenceCreateInfo));
3473	const Unique<VkFence>					fenceOne				(createFence(vk, vkDevice, &fenceCreateInfo));
3474
3475	const VkSubmitInfo						submitInfoCountZero		=
3476	{
3477		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3478		DE_NULL,													// pNext
3479		0u,															// waitSemaphoreCount
3480		DE_NULL,													// pWaitSemaphores
3481		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3482		1u,															// commandBufferCount
3483		&cmdBuffers[0],												// pCommandBuffers
3484		0u,															// signalSemaphoreCount
3485		DE_NULL,													// pSignalSemaphores
3486	};
3487
3488	const VkSubmitInfo						submitInfoCountOne		=
3489	{
3490		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3491		DE_NULL,													// pNext
3492		0u,															// waitSemaphoreCount
3493		DE_NULL,													// pWaitSemaphores
3494		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3495		1u,															// commandBufferCount
3496		&cmdBuffers[1],												// pCommandBuffers
3497		0u,															// signalSemaphoreCount
3498		DE_NULL,													// pSignalSemaphores
3499	};
3500
3501	// Submit the command buffers to the queue
3502	// We're performing two submits to make sure that the first one has
3503	// a chance to be processed before we check the event's status
3504	VK_CHECK(vk.queueSubmit(queue, 0, &submitInfoCountZero, fenceZero.get()));
3505	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfoCountOne, fenceOne.get()));
3506
3507	const VkFence							fences[]				=
3508	{
3509		fenceZero.get(),
3510		fenceOne.get(),
3511	};
3512
3513	// Wait for the queue
3514	VK_CHECK(vk.waitForFences(vkDevice, (deUint32)DE_LENGTH_OF_ARRAY(fences), fences, VK_TRUE, INFINITE_TIMEOUT));
3515
3516	// Check if the first buffer was executed
3517	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3518
3519	if (vk.getEventStatus(vkDevice, events[0]->get()) == VK_EVENT_SET)
3520		testResult = tcu::TestStatus::fail("The first event was signaled.");
3521	else
3522		testResult = tcu::TestStatus::pass("The first submission was ignored.");
3523
3524	return testResult;
3525}
3526
3527tcu::TestStatus submitBufferWaitSingleSemaphore(Context& context)
3528{
3529	const VkDevice							vkDevice				= context.getDevice();
3530	const DeviceInterface&					vk						= context.getDeviceInterface();
3531	const VkQueue							queue					= context.getUniversalQueue();
3532	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3533
3534	const VkCommandPoolCreateInfo			cmdPoolParams			=
3535	{
3536		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// VkStructureType				sType;
3537		DE_NULL,													// const void*					pNext;
3538		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// VkCommandPoolCreateFlags		flags;
3539		queueFamilyIndex,											// deUint32						queueFamilyIndex;
3540	};
3541	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3542
3543	// Command buffer
3544	const VkCommandBufferAllocateInfo		cmdBufParams			=
3545	{
3546		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType				sType;
3547		DE_NULL,													// const void*					pNext;
3548		*cmdPool,													// VkCommandPool				pool;
3549		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// VkCommandBufferLevel			level;
3550		1u,															// uint32_t						bufferCount;
3551	};
3552
3553	// Create two command buffers
3554	const Unique<VkCommandBuffer>			primCmdBuf1				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3555	const Unique<VkCommandBuffer>			primCmdBuf2				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3556
3557	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3558	{
3559		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3560		DE_NULL,													// pNext
3561		0,															// flags
3562		DE_NULL														// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
3563	};
3564
3565	// Fill create info struct for event
3566	const VkEventCreateInfo					eventCreateInfo			=
3567	{
3568		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
3569		DE_NULL,
3570		0u,
3571	};
3572
3573	// create two events that will be used to check if command buffers has been executed
3574	const Unique<VkEvent>					event1					(createEvent(vk, vkDevice, &eventCreateInfo));
3575	const Unique<VkEvent>					event2					(createEvent(vk, vkDevice, &eventCreateInfo));
3576
3577	// reset events
3578	VK_CHECK(vk.resetEvent(vkDevice, *event1));
3579	VK_CHECK(vk.resetEvent(vkDevice, *event2));
3580
3581	// record first command buffer
3582	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
3583	{
3584		// allow execution of event during every stage of pipeline
3585		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3586
3587		// record setting event
3588		vk.cmdSetEvent(*primCmdBuf1, *event1,stageMask);
3589	}
3590	VK_CHECK(vk.endCommandBuffer(*primCmdBuf1));
3591
3592	// record second command buffer
3593	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
3594	{
3595		// allow execution of event during every stage of pipeline
3596		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3597
3598		// record setting event
3599		vk.cmdSetEvent(*primCmdBuf2, *event2,stageMask);
3600	}
3601	VK_CHECK(vk.endCommandBuffer(*primCmdBuf2));
3602
3603	const VkFenceCreateInfo					fenceCreateInfo			=
3604	{
3605		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3606		DE_NULL,
3607		0u,															// flags
3608	};
3609
3610	// create fence to wait for execution of queue
3611	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
3612
3613	// create semaphore for use in this test
3614	const VkSemaphoreCreateInfo				semaphoreCreateInfo		=
3615	{
3616		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,					// sType;
3617		DE_NULL,													// pNext;
3618		0,															// flags;
3619	};
3620
3621	const Unique <VkSemaphore>				semaphore				(createSemaphore(vk, vkDevice, &semaphoreCreateInfo));
3622
3623	// create submit info for first buffer - signalling semaphore
3624	const VkSubmitInfo						submitInfo1				=
3625	{
3626		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3627		DE_NULL,													// pNext
3628		0u,															// waitSemaphoreCount
3629		DE_NULL,													// pWaitSemaphores
3630		DE_NULL,													// pWaitDstStageMask
3631		1,															// commandBufferCount
3632		&primCmdBuf1.get(),											// pCommandBuffers
3633		1u,															// signalSemaphoreCount
3634		&semaphore.get(),											// pSignalSemaphores
3635	};
3636
3637	// Submit the command buffer to the queue
3638	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3639
3640	// wait for end of execution of queue
3641	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3642
3643	// check if buffer has been executed
3644	VkResult result = vk.getEventStatus(vkDevice,*event1);
3645	if (result != VK_EVENT_SET)
3646		return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3647
3648	const VkPipelineStageFlags				waitDstStageFlags		= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3649
3650	// create submit info for second buffer - waiting for semaphore
3651	const VkSubmitInfo						submitInfo2				=
3652	{
3653		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3654		DE_NULL,													// pNext
3655		1u,															// waitSemaphoreCount
3656		&semaphore.get(),											// pWaitSemaphores
3657		&waitDstStageFlags,											// pWaitDstStageMask
3658		1,															// commandBufferCount
3659		&primCmdBuf2.get(),											// pCommandBuffers
3660		0u,															// signalSemaphoreCount
3661		DE_NULL,													// pSignalSemaphores
3662	};
3663
3664	// reset fence, so it can be used again
3665	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3666
3667	// Submit the second command buffer to the queue
3668	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3669
3670	// wait for end of execution of queue
3671	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3672
3673	// check if second buffer has been executed
3674	// if it has been executed, it means that the semaphore was signalled - so test if passed
3675	result = vk.getEventStatus(vkDevice,*event1);
3676	if (result != VK_EVENT_SET)
3677		return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3678
3679	return tcu::TestStatus::pass("Submit Buffer and Wait for Single Semaphore Test succeeded");
3680}
3681
3682tcu::TestStatus submitBufferWaitManySemaphores(Context& context)
3683{
3684	// This test will create numSemaphores semaphores, and signal them in NUM_SEMAPHORES submits to queue
3685	// After that the numSubmissions queue submissions will wait for each semaphore
3686
3687	const deUint32							numSemaphores			= 10u;  // it must be multiply of numSubmission
3688	const deUint32							numSubmissions			= 2u;
3689	const VkDevice							vkDevice				= context.getDevice();
3690	const DeviceInterface&					vk						= context.getDeviceInterface();
3691	const VkQueue							queue					= context.getUniversalQueue();
3692	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3693
3694	const VkCommandPoolCreateInfo			cmdPoolParams			=
3695	{
3696		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// VkStructureType				sType;
3697		DE_NULL,													// const void*					pNext;
3698		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// VkCommandPoolCreateFlags		flags;
3699		queueFamilyIndex,											// deUint32						queueFamilyIndex;
3700	};
3701	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3702
3703	// Command buffer
3704	const VkCommandBufferAllocateInfo		cmdBufParams			=
3705	{
3706		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType				sType;
3707		DE_NULL,													// const void*					pNext;
3708		*cmdPool,													// VkCommandPool				pool;
3709		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// VkCommandBufferLevel			level;
3710		1u,															// uint32_t						bufferCount;
3711	};
3712
3713	// Create command buffer
3714	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3715
3716	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3717	{
3718		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3719		DE_NULL,													// pNext
3720		0,															// flags
3721		DE_NULL														// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
3722	};
3723
3724	// Fill create info struct for event
3725	const VkEventCreateInfo					eventCreateInfo			=
3726	{
3727		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
3728		DE_NULL,
3729		0u,
3730	};
3731
3732	// create event that will be used to check if command buffers has been executed
3733	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
3734
3735	// reset event - at creation state is undefined
3736	VK_CHECK(vk.resetEvent(vkDevice, *event));
3737
3738	// record command buffer
3739	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3740	{
3741		// allow execution of event during every stage of pipeline
3742		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3743
3744		// record setting event
3745		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
3746	}
3747	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
3748
3749	const VkFenceCreateInfo					fenceCreateInfo			=
3750	{
3751		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3752		DE_NULL,
3753		0u,															// flags
3754	};
3755
3756	// create fence to wait for execution of queue
3757	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
3758
3759	// numSemaphores is declared const, so this array can be static
3760	// the semaphores will be destroyed automatically at end of scope
3761	Move <VkSemaphore>						semaphoreArray[numSemaphores];
3762	VkSemaphore								semaphores[numSemaphores];
3763
3764	// prepare create info for semaphores - same for all
3765	const VkSemaphoreCreateInfo				semaphoreCreateInfo		=
3766	{
3767		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,					// sType;
3768		DE_NULL,													// pNext;
3769		0,															// flags;
3770	};
3771
3772	for (deUint32 idx = 0; idx < numSemaphores; ++idx) {
3773		// create semaphores for use in this test
3774		semaphoreArray[idx] = createSemaphore(vk, vkDevice, &semaphoreCreateInfo);
3775		semaphores[idx] = semaphoreArray[idx].get();
3776	};
3777
3778	{
3779		// create submit info for buffer - signal semaphores
3780		const VkSubmitInfo submitInfo1 =
3781		{
3782			VK_STRUCTURE_TYPE_SUBMIT_INFO,							// sType
3783			DE_NULL,												// pNext
3784			0u,														// waitSemaphoreCount
3785			DE_NULL,												// pWaitSemaphores
3786			DE_NULL,												// pWaitDstStageMask
3787			1,														// commandBufferCount
3788			&primCmdBuf.get(),										// pCommandBuffers
3789			numSemaphores,											// signalSemaphoreCount
3790			semaphores												// pSignalSemaphores
3791		};
3792		// Submit the command buffer to the queue
3793		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3794
3795		// wait for end of execution of queue
3796		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3797
3798		// check if buffer has been executed
3799		VkResult result = vk.getEventStatus(vkDevice,*event);
3800		if (result != VK_EVENT_SET)
3801			return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3802
3803		// reset event, so next buffers can set it again
3804		VK_CHECK(vk.resetEvent(vkDevice, *event));
3805
3806		// reset fence, so it can be used again
3807		VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3808	}
3809
3810	const deUint32							numberOfSemaphoresToBeWaitedByOneSubmission	= numSemaphores / numSubmissions;
3811	const std::vector<VkPipelineStageFlags>	waitDstStageFlags							(numberOfSemaphoresToBeWaitedByOneSubmission, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
3812
3813	// the following code waits for the semaphores set above - numSubmissions queues will wait for each semaphore from above
3814	for (deUint32 idxSubmission = 0; idxSubmission < numSubmissions; ++idxSubmission) {
3815
3816		// create submit info for buffer - waiting for semaphore
3817		const VkSubmitInfo				submitInfo2				=
3818		{
3819			VK_STRUCTURE_TYPE_SUBMIT_INFO,												// sType
3820			DE_NULL,																	// pNext
3821			numberOfSemaphoresToBeWaitedByOneSubmission,								// waitSemaphoreCount
3822			semaphores + (numberOfSemaphoresToBeWaitedByOneSubmission * idxSubmission),	// pWaitSemaphores
3823			waitDstStageFlags.data(),													// pWaitDstStageMask
3824			1,																			// commandBufferCount
3825			&primCmdBuf.get(),															// pCommandBuffers
3826			0u,																			// signalSemaphoreCount
3827			DE_NULL,																	// pSignalSemaphores
3828		};
3829
3830		// Submit the second command buffer to the queue
3831		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3832
3833		// wait for 1 second.
3834		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 1000 * 1000 * 1000));
3835
3836		// check if second buffer has been executed
3837		// if it has been executed, it means that the semaphore was signalled - so test if passed
3838		VkResult result = vk.getEventStatus(vkDevice,*event);
3839		if (result != VK_EVENT_SET)
3840			return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3841
3842		// reset fence, so it can be used again
3843		VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3844
3845		// reset event, so next buffers can set it again
3846		VK_CHECK(vk.resetEvent(vkDevice, *event));
3847	}
3848
3849	return tcu::TestStatus::pass("Submit Buffer and Wait for Many Semaphores Test succeeded");
3850}
3851
3852tcu::TestStatus submitBufferNullFence(Context& context)
3853{
3854	const VkDevice							vkDevice				= context.getDevice();
3855	const DeviceInterface&					vk						= context.getDeviceInterface();
3856	const VkQueue							queue					= context.getUniversalQueue();
3857	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3858
3859	const short								BUFFER_COUNT			= 2;
3860
3861	const VkCommandPoolCreateInfo			cmdPoolParams			=
3862	{
3863		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3864		DE_NULL,													// pNext;
3865		0u,															// flags;
3866		queueFamilyIndex,											// queueFamilyIndex;
3867	};
3868	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3869
3870	// Command buffer
3871	const VkCommandBufferAllocateInfo		cmdBufParams			=
3872	{
3873		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3874		DE_NULL,													// pNext;
3875		*cmdPool,													// pool;
3876		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3877		1u,															// bufferCount;
3878	};
3879	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3880	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3881		VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffers[ndx]));
3882
3883	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3884	{
3885		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3886		DE_NULL,													// pNext
3887		0u,															// flags
3888		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3889	};
3890
3891	const VkEventCreateInfo					eventCreateInfo			=
3892	{
3893		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,						// sType;
3894		DE_NULL,													// pNext;
3895		0u,															// flags;
3896	};
3897
3898	std::vector<VkEventSp>					events;
3899	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3900		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL))));
3901
3902	// Record the command buffers
3903	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3904	{
3905		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3906		{
3907			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3908		}
3909		VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3910	}
3911
3912	// We'll use a fence to wait for the execution of the queue
3913	const VkFenceCreateInfo					fenceCreateInfo			=
3914	{
3915		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,						// sType;
3916		DE_NULL,													// pNext;
3917		0u,															// flags
3918	};
3919	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
3920
3921	const VkSubmitInfo						submitInfoNullFence		=
3922	{
3923		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3924		DE_NULL,													// pNext
3925		0u,															// waitSemaphoreCount
3926		DE_NULL,													// pWaitSemaphores
3927		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3928		1u,															// commandBufferCount
3929		&cmdBuffers[0],												// pCommandBuffers
3930		0u,															// signalSemaphoreCount
3931		DE_NULL,													// pSignalSemaphores
3932	};
3933
3934	const VkSubmitInfo						submitInfoNonNullFence	=
3935	{
3936		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3937		DE_NULL,													// pNext
3938		0u,															// waitSemaphoreCount
3939		DE_NULL,													// pWaitSemaphores
3940		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3941		1u,															// commandBufferCount
3942		&cmdBuffers[1],												// pCommandBuffers
3943		0u,															// signalSemaphoreCount
3944		DE_NULL,													// pSignalSemaphores
3945	};
3946
3947	// Perform two submissions - one with no fence, the other one with a valid
3948	// fence Hoping submitting the other buffer will give the first one time to
3949	// execute
3950	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNullFence, DE_NULL));
3951	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNonNullFence, fence.get()));
3952
3953	// Wait for the queue
3954	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3955
3956
3957	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3958
3959	//Fence guaranteed that all buffers submited before fence were executed
3960	if (vk.getEventStatus(vkDevice, events[0]->get()) != VK_EVENT_SET || vk.getEventStatus(vkDevice, events[1]->get()) != VK_EVENT_SET)
3961	{
3962		testResult = tcu::TestStatus::fail("One of the buffers was not executed.");
3963	}
3964	else
3965	{
3966		testResult = tcu::TestStatus::pass("Buffers have been submitted and executed correctly.");
3967	}
3968
3969	vk.queueWaitIdle(queue);
3970	return testResult;
3971}
3972
3973/******** 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) *******/
3974tcu::TestStatus executeSecondaryBufferTest(Context& context)
3975{
3976	const VkDevice							vkDevice				= context.getDevice();
3977	const DeviceInterface&					vk						= context.getDeviceInterface();
3978	const VkQueue							queue					= context.getUniversalQueue();
3979	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3980
3981	const VkCommandPoolCreateInfo			cmdPoolParams			=
3982	{
3983		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3984		DE_NULL,													// pNext;
3985		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
3986		queueFamilyIndex,											// queueFamilyIndex;
3987	};
3988	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3989
3990	// Command buffer
3991	const VkCommandBufferAllocateInfo		cmdBufParams			=
3992	{
3993		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3994		DE_NULL,													// pNext;
3995		*cmdPool,													// commandPool;
3996		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3997		1u,															// bufferCount;
3998	};
3999	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
4000
4001	// Secondary Command buffer
4002	const VkCommandBufferAllocateInfo		secCmdBufParams			=
4003	{
4004		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
4005		DE_NULL,													// pNext;
4006		*cmdPool,													// commandPool;
4007		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
4008		1u,															// bufferCount;
4009	};
4010	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
4011
4012	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
4013	{
4014		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
4015		DE_NULL,													// pNext
4016		0u,															// flags
4017		(const VkCommandBufferInheritanceInfo*)DE_NULL,
4018	};
4019
4020	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
4021	{
4022		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4023		DE_NULL,
4024		DE_NULL,													// renderPass
4025		0u,															// subpass
4026		DE_NULL,													// framebuffer
4027		VK_FALSE,													// occlusionQueryEnable
4028		(VkQueryControlFlags)0u,									// queryFlags
4029		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
4030	};
4031	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
4032	{
4033		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
4034		DE_NULL,													// pNext
4035		0u,															// flags
4036		&secCmdBufInheritInfo,
4037	};
4038
4039	// Fill create info struct for event
4040	const VkEventCreateInfo					eventCreateInfo			=
4041	{
4042		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
4043		DE_NULL,
4044		0u,
4045	};
4046
4047	// create event that will be used to check if secondary command buffer has been executed
4048	const Unique<VkEvent>					event					(createEvent(vk, vkDevice, &eventCreateInfo));
4049
4050	// reset event
4051	VK_CHECK(vk.resetEvent(vkDevice, *event));
4052
4053	// record secondary command buffer
4054	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
4055	{
4056		// allow execution of event during every stage of pipeline
4057		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
4058		// record setting event
4059		vk.cmdSetEvent(*secCmdBuf, *event, stageMask);
4060	}
4061	// end recording of the secondary buffer
4062	VK_CHECK(vk.endCommandBuffer(*secCmdBuf));
4063
4064	// record primary command buffer
4065	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
4066	{
4067		// execute secondary buffer
4068		vk.cmdExecuteCommands(*primCmdBuf, 1u, &secCmdBuf.get());
4069	}
4070	VK_CHECK(vk.endCommandBuffer(*primCmdBuf));
4071
4072	const VkFenceCreateInfo					fenceCreateInfo			=
4073	{
4074		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
4075		DE_NULL,
4076		0u,															// flags
4077	};
4078
4079	// create fence to wait for execution of queue
4080	const Unique<VkFence>					fence					(createFence(vk, vkDevice, &fenceCreateInfo));
4081	const VkSubmitInfo						submitInfo				=
4082	{
4083		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
4084		DE_NULL,													// pNext
4085		0u,															// waitSemaphoreCount
4086		DE_NULL,													// pWaitSemaphores
4087		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
4088		1u,															// commandBufferCount
4089		&primCmdBuf.get(),											// pCommandBuffers
4090		0u,															// signalSemaphoreCount
4091		DE_NULL,													// pSignalSemaphores
4092	};
4093
4094	// submit primary buffer, the secondary should be executed too
4095	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
4096
4097	// wait for end of execution of queue
4098	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
4099
4100	// check if secondary buffer has been executed
4101	VkResult result = vk.getEventStatus(vkDevice, *event);
4102	if (result == VK_EVENT_SET)
4103		return tcu::TestStatus::pass("executeSecondaryBufferTest succeeded");
4104
4105	return tcu::TestStatus::fail("executeSecondaryBufferTest FAILED");
4106}
4107
4108tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context)
4109{
4110	const deUint32							BUFFER_COUNT			= 10u;
4111	const VkDevice							vkDevice				= context.getDevice();
4112	const DeviceInterface&					vk						= context.getDeviceInterface();
4113	const VkQueue							queue					= context.getUniversalQueue();
4114	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
4115
4116	const VkCommandPoolCreateInfo			cmdPoolParams			=
4117	{
4118		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
4119		DE_NULL,													//	const void*					pNext;
4120		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
4121		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
4122	};
4123	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
4124
4125	// Command buffer
4126	const VkCommandBufferAllocateInfo		cmdBufParams			=
4127	{
4128		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
4129		DE_NULL,													//	const void*				pNext;
4130		*cmdPool,													//	VkCommandPool				pool;
4131		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
4132		1u,															//	uint32_t					bufferCount;
4133	};
4134	const Unique<VkCommandBuffer>			primCmdBufOne			(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
4135	const Unique<VkCommandBuffer>			primCmdBufTwo			(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
4136
4137	// Secondary Command buffers params
4138	const VkCommandBufferAllocateInfo		secCmdBufParams			=
4139	{
4140		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
4141		DE_NULL,													//	const void*				pNext;
4142		*cmdPool,													//	VkCommandPool				pool;
4143		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
4144		BUFFER_COUNT,												//	uint32_t					bufferCount;
4145	};
4146	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
4147	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &secCmdBufParams, cmdBuffers));
4148
4149	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
4150	{
4151		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4152		DE_NULL,
4153		0,															// flags
4154		(const VkCommandBufferInheritanceInfo*)DE_NULL,
4155	};
4156
4157	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
4158	{
4159		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4160		DE_NULL,
4161		(VkRenderPass)0u,											// renderPass
4162		0u,															// subpass
4163		(VkFramebuffer)0u,											// framebuffer
4164		VK_FALSE,													// occlusionQueryEnable
4165		(VkQueryControlFlags)0u,									// queryFlags
4166		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
4167	};
4168	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
4169	{
4170		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4171		DE_NULL,
4172		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
4173		&secCmdBufInheritInfo,
4174	};
4175
4176	// Fill create info struct for event
4177	const VkEventCreateInfo					eventCreateInfo			=
4178	{
4179		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
4180		DE_NULL,
4181		0u,
4182	};
4183
4184	// create event that will be used to check if secondary command buffer has been executed
4185	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice, &eventCreateInfo));
4186
4187	// reset event
4188	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
4189
4190	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
4191	{
4192		// record secondary command buffer
4193		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo));
4194		{
4195			// allow execution of event during every stage of pipeline
4196			VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
4197
4198			// wait for event
4199			vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
4200		}
4201		// end recording of secondary buffers
4202		VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
4203	};
4204
4205	// record primary command buffer one
4206	VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
4207	{
4208		// execute one secondary buffer
4209		vk.cmdExecuteCommands(*primCmdBufOne, 1, cmdBuffers );
4210	}
4211	VK_CHECK(vk.endCommandBuffer(*primCmdBufOne));
4212
4213	// record primary command buffer two
4214	VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
4215	{
4216		// execute one secondary buffer with all buffers
4217		vk.cmdExecuteCommands(*primCmdBufTwo, BUFFER_COUNT, cmdBuffers );
4218	}
4219	VK_CHECK(vk.endCommandBuffer(*primCmdBufTwo));
4220
4221	const VkFenceCreateInfo					fenceCreateInfo			=
4222	{
4223		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
4224		DE_NULL,
4225		0u,															// flags
4226	};
4227
4228	// create fence to wait for execution of queue
4229	const Unique<VkFence>					fenceOne				(createFence(vk, vkDevice, &fenceCreateInfo));
4230	const Unique<VkFence>					fenceTwo				(createFence(vk, vkDevice, &fenceCreateInfo));
4231
4232	const VkSubmitInfo						submitInfoOne			=
4233	{
4234		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
4235		DE_NULL,													// pNext
4236		0u,															// waitSemaphoreCount
4237		DE_NULL,													// pWaitSemaphores
4238		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
4239		1,															// commandBufferCount
4240		&primCmdBufOne.get(),										// pCommandBuffers
4241		0u,															// signalSemaphoreCount
4242		DE_NULL,													// pSignalSemaphores
4243	};
4244
4245	// submit primary buffer, the secondary should be executed too
4246	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne));
4247
4248	// wait for buffer to stop at event for 100 microseconds
4249	vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
4250
4251	const VkSubmitInfo						submitInfoTwo			=
4252	{
4253		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
4254		DE_NULL,													// pNext
4255		0u,															// waitSemaphoreCount
4256		DE_NULL,													// pWaitSemaphores
4257		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
4258		1,															// commandBufferCount
4259		&primCmdBufTwo.get(),										// pCommandBuffers
4260		0u,															// signalSemaphoreCount
4261		DE_NULL,													// pSignalSemaphores
4262	};
4263
4264	// submit second primary buffer, the secondary should be executed too
4265	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo));
4266
4267	// wait for all buffers to stop at event for 100 microseconds
4268	vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
4269
4270	// now all buffers are waiting at eventOne
4271	// set event eventOne
4272	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
4273
4274	// wait for end of execution of fenceOne
4275	VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT));
4276
4277	// wait for end of execution of second queue
4278	VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT));
4279
4280	return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded");
4281}
4282
4283/******** 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) **/
4284tcu::TestStatus orderBindPipelineTest(Context& context)
4285{
4286	const DeviceInterface&					vk						= context.getDeviceInterface();
4287	const VkDevice							device					= context.getDevice();
4288	const VkQueue							queue					= context.getUniversalQueue();
4289	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
4290	Allocator&								allocator				= context.getDefaultAllocator();
4291	const ComputeInstanceResultBuffer		result					(vk, device, allocator);
4292
4293	enum
4294	{
4295		ADDRESSABLE_SIZE = 256, // allocate a lot more than required
4296	};
4297
4298	const tcu::Vec4							colorA1					= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
4299	const tcu::Vec4							colorA2					= tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
4300	const tcu::Vec4							colorB1					= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
4301	const tcu::Vec4							colorB2					= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
4302
4303	const deUint32							dataOffsetA				= (0u);
4304	const deUint32							dataOffsetB				= (0u);
4305	const deUint32							viewOffsetA				= (0u);
4306	const deUint32							viewOffsetB				= (0u);
4307	const deUint32							bufferSizeA				= dataOffsetA + ADDRESSABLE_SIZE;
4308	const deUint32							bufferSizeB				= dataOffsetB + ADDRESSABLE_SIZE;
4309
4310	de::MovePtr<Allocation>					bufferMemA;
4311	const Unique<VkBuffer>					bufferA					(createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context));
4312
4313	de::MovePtr<Allocation>					bufferMemB;
4314	const Unique<VkBuffer>					bufferB					(createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB, context));
4315
4316	const Unique<VkDescriptorSetLayout>		descriptorSetLayout		(createDescriptorSetLayout(context));
4317	const Unique<VkDescriptorPool>			descriptorPool			(createDescriptorPool(context));
4318	const Unique<VkDescriptorSet>			descriptorSet			(createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, result.getBuffer(), context));
4319	const VkDescriptorSet					descriptorSets[]		= { *descriptorSet };
4320	const int								numDescriptorSets		= DE_LENGTH_OF_ARRAY(descriptorSets);
4321
4322	const VkPipelineLayoutCreateInfo layoutCreateInfo =
4323	{
4324		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
4325		DE_NULL,													// pNext
4326		(VkPipelineLayoutCreateFlags)0,
4327		numDescriptorSets,											// setLayoutCount
4328		&descriptorSetLayout.get(),									// pSetLayouts
4329		0u,															// pushConstantRangeCount
4330		DE_NULL,													// pPushConstantRanges
4331	};
4332	Unique<VkPipelineLayout>				pipelineLayout			(createPipelineLayout(vk, device, &layoutCreateInfo));
4333
4334	const Unique<VkShaderModule>			computeModuleGood		(createShaderModule(vk, device, context.getBinaryCollection().get("compute_good"), (VkShaderModuleCreateFlags)0u));
4335	const Unique<VkShaderModule>			computeModuleBad		(createShaderModule(vk, device, context.getBinaryCollection().get("compute_bad"),  (VkShaderModuleCreateFlags)0u));
4336
4337	const VkPipelineShaderStageCreateInfo	shaderCreateInfoGood	=
4338	{
4339		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
4340		DE_NULL,
4341		(VkPipelineShaderStageCreateFlags)0,
4342		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
4343		*computeModuleGood,											// shader
4344		"main",
4345		DE_NULL,													// pSpecializationInfo
4346	};
4347
4348	const VkPipelineShaderStageCreateInfo	shaderCreateInfoBad	=
4349	{
4350		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
4351		DE_NULL,
4352		(vk::VkPipelineShaderStageCreateFlags)0,
4353		vk::VK_SHADER_STAGE_COMPUTE_BIT,							// stage
4354		*computeModuleBad,											// shader
4355		"main",
4356		DE_NULL,													// pSpecializationInfo
4357	};
4358
4359	const VkComputePipelineCreateInfo		createInfoGood			=
4360	{
4361		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
4362		DE_NULL,
4363		0u,															// flags
4364		shaderCreateInfoGood,										// cs
4365		*pipelineLayout,											// layout
4366		(vk::VkPipeline)0,											// basePipelineHandle
4367		0u,															// basePipelineIndex
4368	};
4369
4370	const VkComputePipelineCreateInfo		createInfoBad			=
4371	{
4372		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
4373		DE_NULL,
4374		0u,															// flags
4375		shaderCreateInfoBad,										// cs
4376		*pipelineLayout,											// descriptorSetLayout.get()
4377		(VkPipeline)0,												// basePipelineHandle
4378		0u,															// basePipelineIndex
4379	};
4380
4381	const Unique<VkPipeline>				pipelineGood			(createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoGood));
4382	const Unique<VkPipeline>				pipelineBad				(createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoBad));
4383
4384	const VkAccessFlags						inputBit				= (VK_ACCESS_UNIFORM_READ_BIT);
4385	const VkBufferMemoryBarrier				bufferBarriers[]		=
4386	{
4387		{
4388			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
4389			DE_NULL,
4390			VK_ACCESS_HOST_WRITE_BIT,									// outputMask
4391			inputBit,													// inputMask
4392			VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
4393			VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
4394			*bufferA,													// buffer
4395			(VkDeviceSize)0u,											// offset
4396			(VkDeviceSize)bufferSizeA,									// size
4397		},
4398		{
4399			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
4400			DE_NULL,
4401			VK_ACCESS_HOST_WRITE_BIT,									// outputMask
4402			inputBit,													// inputMask
4403			VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
4404			VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
4405			*bufferB,													// buffer
4406			(VkDeviceSize)0u,											// offset
4407			(VkDeviceSize)bufferSizeB,									// size
4408		}
4409	};
4410
4411	const deUint32							numSrcBuffers			= 1u;
4412
4413	const deUint32* const					dynamicOffsets			= (DE_NULL);
4414	const deUint32							numDynamicOffsets		= (0);
4415	const int								numPreBarriers			= numSrcBuffers;
4416	const vk::VkBufferMemoryBarrier* const	postBarriers			= result.getResultReadBarrier();
4417	const int								numPostBarriers			= 1;
4418	const tcu::Vec4							refQuadrantValue14		= (colorA2);
4419	const tcu::Vec4							refQuadrantValue23		= (colorA1);
4420	const tcu::Vec4							references[4]			=
4421	{
4422		refQuadrantValue14,
4423		refQuadrantValue23,
4424		refQuadrantValue23,
4425		refQuadrantValue14,
4426	};
4427	tcu::Vec4								results[4];
4428
4429	// submit and wait begin
4430
4431	const tcu::UVec3 numWorkGroups = tcu::UVec3(4, 1u, 1);
4432
4433	const VkCommandPoolCreateInfo			cmdPoolCreateInfo		=
4434	{
4435		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
4436		DE_NULL,													// pNext
4437		VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,						// flags
4438		queueFamilyIndex,											// queueFamilyIndex
4439	};
4440	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, &cmdPoolCreateInfo));
4441
4442	const VkFenceCreateInfo					fenceCreateInfo			=
4443	{
4444		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
4445		DE_NULL,
4446		0u,			// flags
4447	};
4448
4449	const VkCommandBufferAllocateInfo		cmdBufCreateInfo		=
4450	{
4451		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType
4452		DE_NULL,													// pNext
4453		*cmdPool,													// commandPool
4454		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level
4455		1u,															// bufferCount;
4456	};
4457
4458	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
4459	{
4460		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
4461		DE_NULL,													// pNext
4462		0u,															// flags
4463		(const VkCommandBufferInheritanceInfo*)DE_NULL,
4464	};
4465
4466	const Unique<VkFence>					cmdCompleteFence		(createFence(vk, device, &fenceCreateInfo));
4467	const Unique<VkCommandBuffer>			cmd						(allocateCommandBuffer(vk, device, &cmdBufCreateInfo));
4468
4469	VK_CHECK(vk.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
4470
4471	vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineBad);
4472	vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineGood);
4473	vk.cmdBindDescriptorSets(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, numDynamicOffsets, dynamicOffsets);
4474
4475	if (numPreBarriers)
4476		vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0,
4477							  0, (const VkMemoryBarrier*)DE_NULL,
4478							  numPreBarriers, bufferBarriers,
4479							  0, (const VkImageMemoryBarrier*)DE_NULL);
4480
4481	vk.cmdDispatch(*cmd, numWorkGroups.x(), numWorkGroups.y(), numWorkGroups.z());
4482	vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
4483						  0, (const VkMemoryBarrier*)DE_NULL,
4484						  numPostBarriers, postBarriers,
4485						  0, (const VkImageMemoryBarrier*)DE_NULL);
4486	VK_CHECK(vk.endCommandBuffer(*cmd));
4487
4488	// run
4489	// submit second primary buffer, the secondary should be executed too
4490	const VkSubmitInfo						submitInfo				=
4491	{
4492		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
4493		DE_NULL,													// pNext
4494		0u,															// waitSemaphoreCount
4495		DE_NULL,													// pWaitSemaphores
4496		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
4497		1,															// commandBufferCount
4498		&cmd.get(),													// pCommandBuffers
4499		0u,															// signalSemaphoreCount
4500		DE_NULL,													// pSignalSemaphores
4501	};
4502	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *cmdCompleteFence));
4503
4504	VK_CHECK(vk.waitForFences(device, 1u, &cmdCompleteFence.get(), 0u, INFINITE_TIMEOUT)); // \note: timeout is failure
4505	VK_CHECK(vk.resetFences(device, 1u, &cmdCompleteFence.get()));
4506
4507	// submit and wait end
4508	result.readResultContentsTo(&results);
4509
4510	// verify
4511	if (results[0] == references[0] &&
4512		results[1] == references[1] &&
4513		results[2] == references[2] &&
4514		results[3] == references[3])
4515	{
4516		return tcu::TestStatus::pass("Pass");
4517	}
4518	else if (results[0] == tcu::Vec4(-1.0f) &&
4519			 results[1] == tcu::Vec4(-1.0f) &&
4520			 results[2] == tcu::Vec4(-1.0f) &&
4521			 results[3] == tcu::Vec4(-1.0f))
4522	{
4523		context.getTestContext().getLog()
4524		<< tcu::TestLog::Message
4525		<< "Result buffer was not written to."
4526		<< tcu::TestLog::EndMessage;
4527		return tcu::TestStatus::fail("Result buffer was not written to");
4528	}
4529	else
4530	{
4531		context.getTestContext().getLog()
4532		<< tcu::TestLog::Message
4533		<< "Error expected ["
4534		<< references[0] << ", "
4535		<< references[1] << ", "
4536		<< references[2] << ", "
4537		<< references[3] << "], got ["
4538		<< results[0] << ", "
4539		<< results[1] << ", "
4540		<< results[2] << ", "
4541		<< results[3] << "]"
4542		<< tcu::TestLog::EndMessage;
4543		return tcu::TestStatus::fail("Invalid result values");
4544	}
4545}
4546
4547// Shaders
4548void genComputeSource (SourceCollections& programCollection)
4549{
4550	const char* const						versionDecl				= glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4551	std::ostringstream						bufGood;
4552
4553	bufGood << versionDecl << "\n"
4554	<< ""
4555	<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4556	<< "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4557	<< "{\n"
4558	<< "	highp vec4 colorA;\n"
4559	<< "	highp vec4 colorB;\n"
4560	<< "} b_instance;\n"
4561	<< "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4562	<< "{\n"
4563	<< "	highp vec4 read_colors[4];\n"
4564	<< "} b_out;\n"
4565	<< "void main(void)\n"
4566	<< "{\n"
4567	<< "	highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4568	<< "	highp vec4 result_color;\n"
4569	<< "	if (quadrant_id == 1 || quadrant_id == 2)\n"
4570	<< "		result_color = b_instance.colorA;\n"
4571	<< "	else\n"
4572	<< "		result_color = b_instance.colorB;\n"
4573	<< "	b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
4574	<< "}\n";
4575
4576	programCollection.glslSources.add("compute_good") << glu::ComputeSource(bufGood.str());
4577
4578	std::ostringstream	bufBad;
4579
4580	bufBad	<< versionDecl << "\n"
4581	<< ""
4582	<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4583	<< "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4584	<< "{\n"
4585	<< "	highp vec4 colorA;\n"
4586	<< "	highp vec4 colorB;\n"
4587	<< "} b_instance;\n"
4588	<< "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4589	<< "{\n"
4590	<< "	highp vec4 read_colors[4];\n"
4591	<< "} b_out;\n"
4592	<< "void main(void)\n"
4593	<< "{\n"
4594	<< "	highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4595	<< "	highp vec4 result_color;\n"
4596	<< "	if (quadrant_id == 1 || quadrant_id == 2)\n"
4597	<< "		result_color = b_instance.colorA;\n"
4598	<< "	else\n"
4599	<< "		result_color = b_instance.colorB;\n"
4600	<< "	b_out.read_colors[gl_WorkGroupID.x] = vec4(0.0, 0.0, 0.0, 0.0);\n"
4601	<< "}\n";
4602
4603	programCollection.glslSources.add("compute_bad") << glu::ComputeSource(bufBad.str());
4604}
4605
4606void genComputeIncrementSource (SourceCollections& programCollection)
4607{
4608	const char* const						versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4609	std::ostringstream						bufIncrement;
4610
4611	bufIncrement << versionDecl << "\n"
4612		<< ""
4613		<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4614		<< "layout(set = 0, binding = 0, std140) buffer InOutBuf\n"
4615		<< "{\n"
4616		<< "    coherent uint count;\n"
4617		<< "} b_in_out;\n"
4618		<< "void main(void)\n"
4619		<< "{\n"
4620		<< "	atomicAdd(b_in_out.count, 1u);\n"
4621		<< "}\n";
4622
4623	programCollection.glslSources.add("compute_increment") << glu::ComputeSource(bufIncrement.str());
4624}
4625
4626} // anonymous
4627
4628tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx)
4629{
4630	de::MovePtr<tcu::TestCaseGroup>	commandBuffersTests	(new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests"));
4631
4632	/* 19.1. Command Pools (5.1 in VK 1.0 Spec) */
4633	addFunctionCase				(commandBuffersTests.get(), "pool_create_null_params",			"",	createPoolNullParamsTest);
4634	addFunctionCase				(commandBuffersTests.get(), "pool_create_non_null_allocator",	"",	createPoolNonNullAllocatorTest);
4635	addFunctionCase				(commandBuffersTests.get(), "pool_create_transient_bit",		"",	createPoolTransientBitTest);
4636	addFunctionCase				(commandBuffersTests.get(), "pool_create_reset_bit",			"",	createPoolResetBitTest);
4637	addFunctionCase				(commandBuffersTests.get(), "pool_reset_release_res",			"",	resetPoolReleaseResourcesBitTest);
4638	addFunctionCase				(commandBuffersTests.get(), "pool_reset_no_flags_res",			"",	resetPoolNoFlagsTest);
4639	addFunctionCase				(commandBuffersTests.get(), "pool_reset_reuse",					"",	resetPoolReuseTest);
4640	/* 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) */
4641	addFunctionCase				(commandBuffersTests.get(), "allocate_single_primary",			"", allocatePrimaryBufferTest);
4642	addFunctionCase				(commandBuffersTests.get(), "allocate_many_primary",			"",	allocateManyPrimaryBuffersTest);
4643	addFunctionCase				(commandBuffersTests.get(), "allocate_single_secondary",		"", allocateSecondaryBufferTest);
4644	addFunctionCase				(commandBuffersTests.get(), "allocate_many_secondary",			"", allocateManySecondaryBuffersTest);
4645	addFunctionCase				(commandBuffersTests.get(), "execute_small_primary",			"",	executePrimaryBufferTest);
4646	addFunctionCase				(commandBuffersTests.get(), "execute_large_primary",			"",	executeLargePrimaryBufferTest);
4647	addFunctionCase				(commandBuffersTests.get(), "reset_implicit",					"", resetBufferImplicitlyTest);
4648	addFunctionCase				(commandBuffersTests.get(), "trim_command_pool",				"", trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4649	addFunctionCase				(commandBuffersTests.get(), "trim_command_pool_secondary",		"", trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4650	/* 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) */
4651	addFunctionCase				(commandBuffersTests.get(), "record_single_primary",			"",	recordSinglePrimaryBufferTest);
4652	addFunctionCase				(commandBuffersTests.get(), "record_many_primary",				"", recordLargePrimaryBufferTest);
4653	addFunctionCase				(commandBuffersTests.get(), "record_single_secondary",			"",	recordSingleSecondaryBufferTest);
4654	addFunctionCase				(commandBuffersTests.get(), "record_many_secondary",			"", recordLargeSecondaryBufferTest);
4655	addFunctionCase				(commandBuffersTests.get(), "submit_twice_primary",				"",	submitPrimaryBufferTwiceTest);
4656	addFunctionCase				(commandBuffersTests.get(), "submit_twice_secondary",			"",	submitSecondaryBufferTwiceTest);
4657	addFunctionCase				(commandBuffersTests.get(), "record_one_time_submit_primary",	"",	oneTimeSubmitFlagPrimaryBufferTest);
4658	addFunctionCase				(commandBuffersTests.get(), "record_one_time_submit_secondary",	"",	oneTimeSubmitFlagSecondaryBufferTest);
4659	addFunctionCase				(commandBuffersTests.get(), "render_pass_continue",				"",	renderPassContinueTest);
4660	addFunctionCase				(commandBuffersTests.get(), "record_simul_use_primary",			"",	simultaneousUsePrimaryBufferTest);
4661	addFunctionCase				(commandBuffersTests.get(), "record_simul_use_secondary",		"",	simultaneousUseSecondaryBufferTest);
4662	addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_one_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferOnePrimaryBufferTest);
4663	addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_two_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferTwoPrimaryBuffersTest);
4664	addFunctionCase				(commandBuffersTests.get(), "record_query_precise_w_flag",		"",	recordBufferQueryPreciseWithFlagTest);
4665	addFunctionCase				(commandBuffersTests.get(), "record_query_imprecise_w_flag",	"",	recordBufferQueryImpreciseWithFlagTest);
4666	addFunctionCase				(commandBuffersTests.get(), "record_query_imprecise_wo_flag",	"",	recordBufferQueryImpreciseWithoutFlagTest);
4667	/* 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) */
4668	addFunctionCase				(commandBuffersTests.get(), "submit_count_non_zero",			"", submitBufferCountNonZero);
4669	addFunctionCase				(commandBuffersTests.get(), "submit_count_equal_zero",			"", submitBufferCountEqualZero);
4670	addFunctionCase				(commandBuffersTests.get(), "submit_wait_single_semaphore",		"", submitBufferWaitSingleSemaphore);
4671	addFunctionCase				(commandBuffersTests.get(), "submit_wait_many_semaphores",		"", submitBufferWaitManySemaphores);
4672	addFunctionCase				(commandBuffersTests.get(), "submit_null_fence",				"", submitBufferNullFence);
4673	/* 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) */
4674	addFunctionCase				(commandBuffersTests.get(), "secondary_execute",				"",	executeSecondaryBufferTest);
4675	addFunctionCase				(commandBuffersTests.get(), "secondary_execute_twice",			"",	executeSecondaryBufferTwiceTest);
4676	/* 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) */
4677	addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_bind_pipeline",				"", genComputeSource, orderBindPipelineTest);
4678
4679	return commandBuffersTests.release();
4680}
4681
4682} // api
4683} // vkt
4684
4685