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