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