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