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