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