• 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 
simultaneousUsePrimaryBufferTest(Context & context)1748 tcu::TestStatus simultaneousUsePrimaryBufferTest(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 
1755 	const VkCommandPoolCreateInfo			cmdPoolParams			=
1756 	{
1757 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1758 		DE_NULL,													//	const void*					pNext;
1759 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1760 		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1761 	};
1762 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1763 
1764 	// Command buffer
1765 	const VkCommandBufferAllocateInfo		cmdBufParams			=
1766 	{
1767 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType				sType;
1768 		DE_NULL,													//	const void*					pNext;
1769 		*cmdPool,													//	VkCommandPool				pool;
1770 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1771 		1u,															//	uint32_t					bufferCount;
1772 	};
1773 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1774 
1775 	// create event that will be used to check if secondary command buffer has been executed
1776 	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice));
1777 	const Unique<VkEvent>					eventTwo				(createEvent(vk, vkDevice));
1778 
1779 	// reset event
1780 	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1781 
1782 	// record primary command buffer
1783 	beginCommandBuffer(vk, *primCmdBuf, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
1784 	{
1785 		// wait for event
1786 		vk.cmdWaitEvents(*primCmdBuf, 1u, &eventOne.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
1787 
1788 		// Set the second event
1789 		vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1790 	}
1791 	endCommandBuffer(vk, *primCmdBuf);
1792 
1793 	// create fence to wait for execution of queue
1794 	const Unique<VkFence>					fence1					(createFence(vk, vkDevice));
1795 	const Unique<VkFence>					fence2					(createFence(vk, vkDevice));
1796 
1797 	const VkSubmitInfo						submitInfo				=
1798 	{
1799 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1800 		DE_NULL,													// pNext
1801 		0u,															// waitSemaphoreCount
1802 		DE_NULL,													// pWaitSemaphores
1803 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1804 		1,															// commandBufferCount
1805 		&primCmdBuf.get(),											// pCommandBuffers
1806 		0u,															// signalSemaphoreCount
1807 		DE_NULL,													// pSignalSemaphores
1808 	};
1809 
1810 	// submit first buffer
1811 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence1));
1812 
1813 	// submit second buffer
1814 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence2));
1815 
1816 	// wait for both buffer to stop at event for 100 microseconds
1817 	vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, 100000);
1818 	vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, 100000);
1819 
1820 	// set event
1821 	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
1822 
1823 	// wait for end of execution of the first buffer
1824 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, INFINITE_TIMEOUT));
1825 	// wait for end of execution of the second buffer
1826 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, INFINITE_TIMEOUT));
1827 
1828 	// TODO: this will be true if the command buffer was executed only once
1829 	// TODO: add some test that will say if it was executed twice
1830 
1831 	// check if buffer has been executed
1832 	VkResult result = vk.getEventStatus(vkDevice, *eventTwo);
1833 	if (result == VK_EVENT_SET)
1834 		return tcu::TestStatus::pass("simultaneous use - primary buffers test succeeded");
1835 	else
1836 		return tcu::TestStatus::fail("simultaneous use - primary buffers test FAILED");
1837 }
1838 
simultaneousUseSecondaryBufferTest(Context & context)1839 tcu::TestStatus simultaneousUseSecondaryBufferTest(Context& context)
1840 {
1841 	const VkDevice							vkDevice				= context.getDevice();
1842 	const DeviceInterface&					vk						= context.getDeviceInterface();
1843 	const VkQueue							queue					= context.getUniversalQueue();
1844 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1845 
1846 	const VkCommandPoolCreateInfo			cmdPoolParams			=
1847 	{
1848 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1849 		DE_NULL,													//	const void*					pNext;
1850 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1851 		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1852 	};
1853 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
1854 
1855 	// Command buffer
1856 	const VkCommandBufferAllocateInfo		cmdBufParams			=
1857 	{
1858 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1859 		DE_NULL,													//	const void*				pNext;
1860 		*cmdPool,													//	VkCommandPool				pool;
1861 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1862 		1u,															//	uint32_t					bufferCount;
1863 	};
1864 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1865 
1866 	// Secondary Command buffer params
1867 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
1868 	{
1869 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1870 		DE_NULL,													//	const void*				pNext;
1871 		*cmdPool,													//	VkCommandPool				pool;
1872 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
1873 		1u,															//	uint32_t					bufferCount;
1874 	};
1875 	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1876 
1877 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
1878 	{
1879 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1880 		DE_NULL,
1881 		(VkRenderPass)0u,											// renderPass
1882 		0u,															// subpass
1883 		(VkFramebuffer)0u,											// framebuffer
1884 		VK_FALSE,													// occlusionQueryEnable
1885 		(VkQueryControlFlags)0u,									// queryFlags
1886 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
1887 	};
1888 	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
1889 	{
1890 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1891 		DE_NULL,
1892 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
1893 		&secCmdBufInheritInfo,
1894 	};
1895 
1896 	// create event that will be used to check if secondary command buffer has been executed
1897 	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice));
1898 	const Unique<VkEvent>					eventTwo				(createEvent(vk, vkDevice));
1899 
1900 	// reset event
1901 	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1902 	VK_CHECK(vk.resetEvent(vkDevice, *eventTwo));
1903 
1904 	// record secondary command buffer
1905 	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1906 	{
1907 		// allow execution of event during every stage of pipeline
1908 		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1909 
1910 		// wait for event
1911 		vk.cmdWaitEvents(*secCmdBuf, 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
1912 
1913 		// reset event
1914 		vk.cmdSetEvent(*secCmdBuf, *eventTwo, stageMask);
1915 	}
1916 	// end recording of secondary buffers
1917 	endCommandBuffer(vk, *secCmdBuf);
1918 
1919 	// record primary command buffer
1920 	beginCommandBuffer(vk, *primCmdBuf, 0u);
1921 	{
1922 		// execute secondary buffer
1923 		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
1924 	}
1925 	endCommandBuffer(vk, *primCmdBuf);
1926 
1927 	// create fence to wait for execution of queue
1928 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
1929 
1930 	const VkSubmitInfo						submitInfo				=
1931 	{
1932 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
1933 		DE_NULL,													// pNext
1934 		0u,															// waitSemaphoreCount
1935 		DE_NULL,													// pWaitSemaphores
1936 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
1937 		1,															// commandBufferCount
1938 		&primCmdBuf.get(),											// pCommandBuffers
1939 		0u,															// signalSemaphoreCount
1940 		DE_NULL,													// pSignalSemaphores
1941 	};
1942 
1943 	// submit primary buffer, the secondary should be executed too
1944 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1945 
1946 	// wait for both buffers to stop at event for 100 microseconds
1947 	vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 100000);
1948 
1949 	// set event
1950 	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
1951 
1952 	// wait for end of execution of queue
1953 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1954 
1955 	// TODO: this will be true if the command buffer was executed only once
1956 	// TODO: add some test that will say if it was executed twice
1957 
1958 	// check if secondary buffer has been executed
1959 	VkResult result = vk.getEventStatus(vkDevice,*eventTwo);
1960 	if (result == VK_EVENT_SET)
1961 		return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
1962 	else
1963 		return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
1964 }
1965 
simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context & context)1966 tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& context)
1967 {
1968 	const VkDevice							vkDevice = context.getDevice();
1969 	const DeviceInterface&					vk = context.getDeviceInterface();
1970 	const VkQueue							queue = context.getUniversalQueue();
1971 	const deUint32							queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1972 	Allocator&								allocator = context.getDefaultAllocator();
1973 	const ComputeInstanceResultBuffer		result(vk, vkDevice, allocator, 0.0f);
1974 
1975 	const VkCommandPoolCreateInfo			cmdPoolParams =
1976 	{
1977 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
1978 		DE_NULL,													//	const void*					pNext;
1979 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
1980 		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
1981 	};
1982 	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
1983 
1984 	// Command buffer
1985 	const VkCommandBufferAllocateInfo		cmdBufParams =
1986 	{
1987 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1988 		DE_NULL,													//	const void*				pNext;
1989 		*cmdPool,													//	VkCommandPool				pool;
1990 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
1991 		1u,															//	uint32_t					bufferCount;
1992 	};
1993 	const Unique<VkCommandBuffer>			primCmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1994 
1995 	// Secondary Command buffer params
1996 	const VkCommandBufferAllocateInfo		secCmdBufParams =
1997 	{
1998 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
1999 		DE_NULL,													//	const void*				pNext;
2000 		*cmdPool,													//	VkCommandPool				pool;
2001 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2002 		1u,															//	uint32_t					bufferCount;
2003 	};
2004 	const Unique<VkCommandBuffer>			secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2005 
2006 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo =
2007 	{
2008 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2009 		DE_NULL,
2010 		(VkRenderPass)0u,
2011 		0u,															// subpass
2012 		(VkFramebuffer)0u,
2013 		VK_FALSE,													// occlusionQueryEnable
2014 		(VkQueryControlFlags)0u,
2015 		(VkQueryPipelineStatisticFlags)0u,
2016 	};
2017 	const VkCommandBufferBeginInfo			secCmdBufBeginInfo =
2018 	{
2019 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2020 		DE_NULL,
2021 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2022 		&secCmdBufInheritInfo,
2023 	};
2024 
2025 	const deUint32							offset = (0u);
2026 	const deUint32							addressableSize = 256;
2027 	const deUint32							dataSize = 8;
2028 	de::MovePtr<Allocation>					bufferMem;
2029 	const Unique<VkBuffer>					buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2030 	// Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2031 	const Unique<VkDescriptorSetLayout>		descriptorSetLayout(createDescriptorSetLayout(context));
2032 	const Unique<VkDescriptorPool>			descriptorPool(createDescriptorPool(context));
2033 	const Unique<VkDescriptorSet>			descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2034 	const VkDescriptorSet					descriptorSets[] = { *descriptorSet };
2035 	const int								numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2036 
2037 	const VkPipelineLayoutCreateInfo layoutCreateInfo =
2038 	{
2039 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
2040 		DE_NULL,													// pNext
2041 		(VkPipelineLayoutCreateFlags)0,
2042 		numDescriptorSets,											// setLayoutCount
2043 		&descriptorSetLayout.get(),									// pSetLayouts
2044 		0u,															// pushConstantRangeCount
2045 		DE_NULL,													// pPushConstantRanges
2046 	};
2047 	Unique<VkPipelineLayout>				pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2048 
2049 	const Unique<VkShaderModule>			computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2050 
2051 	const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
2052 	{
2053 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2054 		DE_NULL,
2055 		(VkPipelineShaderStageCreateFlags)0,
2056 		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
2057 		*computeModule,												// shader
2058 		"main",
2059 		DE_NULL,													// pSpecializationInfo
2060 	};
2061 
2062 	const VkComputePipelineCreateInfo		pipelineCreateInfo =
2063 	{
2064 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2065 		DE_NULL,
2066 		0u,															// flags
2067 		shaderCreateInfo,											// cs
2068 		*pipelineLayout,											// layout
2069 		(vk::VkPipeline)0,											// basePipelineHandle
2070 		0u,															// basePipelineIndex
2071 	};
2072 
2073 	const VkBufferMemoryBarrier				bufferBarrier =
2074 	{
2075 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// sType
2076 		DE_NULL,													// pNext
2077 		VK_ACCESS_SHADER_WRITE_BIT,									// srcAccessMask
2078 		VK_ACCESS_HOST_READ_BIT,									// dstAccessMask
2079 		VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
2080 		VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
2081 		*buffer,													// buffer
2082 		(VkDeviceSize)0u,											// offset
2083 		(VkDeviceSize)VK_WHOLE_SIZE,								// size
2084 	};
2085 
2086 	const Unique<VkPipeline>				pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2087 
2088 	// record secondary command buffer
2089 	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2090 	{
2091 		vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2092 		vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2093 		vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2094 		vk.cmdPipelineBarrier(*secCmdBuf, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
2095 						  0, (const VkMemoryBarrier*)DE_NULL,
2096 						  1, &bufferBarrier,
2097 						  0, (const VkImageMemoryBarrier*)DE_NULL);
2098 	}
2099 	// end recording of secondary buffer
2100 	endCommandBuffer(vk, *secCmdBuf);
2101 
2102 	// record primary command buffer
2103 	beginCommandBuffer(vk, *primCmdBuf, 0u);
2104 	{
2105 		// execute secondary buffer twice in same primary
2106 		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2107 		vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2108 	}
2109 	endCommandBuffer(vk, *primCmdBuf);
2110 
2111 	submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
2112 
2113 	deUint32 resultCount;
2114 	result.readResultContentsTo(&resultCount);
2115 	// check if secondary buffer has been executed
2116 	if (resultCount == 2)
2117 		return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
2118 	else
2119 		return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2120 }
2121 
2122 enum class BadInheritanceInfoCase
2123 {
2124 	RANDOM_PTR = 0,
2125 	RANDOM_PTR_CONTINUATION,
2126 	RANDOM_DATA_PTR,
2127 	INVALID_STRUCTURE_TYPE,
2128 	VALID_NONSENSE_TYPE,
2129 };
2130 
badInheritanceInfoTest(Context & context,BadInheritanceInfoCase testCase)2131 tcu::TestStatus badInheritanceInfoTest (Context& context, BadInheritanceInfoCase testCase)
2132 {
2133 	const auto&							vkd					= context.getDeviceInterface();
2134 	const auto							device				= context.getDevice();
2135 	const auto							queue				= context.getUniversalQueue();
2136 	const auto							queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2137 	auto&								allocator			= context.getDefaultAllocator();
2138 	const ComputeInstanceResultBuffer	result				(vkd, device, allocator, 0.0f);
2139 
2140 	// Command pool and command buffer.
2141 	const auto							cmdPool			= makeCommandPool(vkd, device, queueFamilyIndex);
2142 	const auto							cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2143 	const auto							cmdBuffer		= cmdBufferPtr.get();
2144 
2145 	// Buffers, descriptor set layouts and descriptor sets.
2146 	const deUint32							offset			= 0u;
2147 	const deUint32							addressableSize	= 256u;
2148 	const deUint32							dataSize		= 8u;
2149 
2150 	// The uniform buffer will not be used by the shader but is needed by auxiliar functions here.
2151 	de::MovePtr<Allocation>					bufferMem;
2152 	const Unique<VkBuffer>					buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2153 
2154 	const Unique<VkDescriptorSetLayout>		descriptorSetLayout	(createDescriptorSetLayout(context));
2155 	const Unique<VkDescriptorPool>			descriptorPool		(createDescriptorPool(context));
2156 	const Unique<VkDescriptorSet>			descriptorSet		(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2157 	const VkDescriptorSet					descriptorSets[]	= { *descriptorSet };
2158 	const int								numDescriptorSets	= DE_LENGTH_OF_ARRAY(descriptorSets);
2159 
2160 	// Pipeline layout.
2161 	const auto								pipelineLayout		= makePipelineLayout(vkd, device, descriptorSetLayout.get());
2162 
2163 	// Compute shader module.
2164 	const Unique<VkShaderModule>			computeModule		(createShaderModule(vkd, device, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2165 
2166 	const VkPipelineShaderStageCreateInfo	shaderCreateInfo	=
2167 	{
2168 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2169 		DE_NULL,
2170 		(VkPipelineShaderStageCreateFlags)0,
2171 		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
2172 		*computeModule,												// shader
2173 		"main",
2174 		DE_NULL,													// pSpecializationInfo
2175 	};
2176 
2177 	const VkComputePipelineCreateInfo		pipelineCreateInfo	=
2178 	{
2179 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2180 		DE_NULL,
2181 		0u,															// flags
2182 		shaderCreateInfo,											// cs
2183 		*pipelineLayout,											// layout
2184 		(vk::VkPipeline)0,											// basePipelineHandle
2185 		0u,															// basePipelineIndex
2186 	};
2187 
2188 	const Unique<VkPipeline>				pipeline			(createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo));
2189 
2190 	// Compute to host barrier to read result.
2191 	const VkBufferMemoryBarrier				bufferBarrier		=
2192 	{
2193 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// sType
2194 		DE_NULL,													// pNext
2195 		VK_ACCESS_SHADER_WRITE_BIT,									// srcAccessMask
2196 		VK_ACCESS_HOST_READ_BIT,									// dstAccessMask
2197 		VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
2198 		VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
2199 		*buffer,													// buffer
2200 		(VkDeviceSize)0u,											// offset
2201 		(VkDeviceSize)VK_WHOLE_SIZE,								// size
2202 	};
2203 
2204 	// Record command buffer and submit it.
2205 	VkCommandBufferBeginInfo				beginInfo			=
2206 	{
2207 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	//	VkStructureType							sType;
2208 		nullptr,										//	const void*								pNext;
2209 		0u,												//	VkCommandBufferUsageFlags				flags;
2210 		nullptr,										//	const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
2211 	};
2212 
2213 	// Structures used in different test types.
2214 	VkCommandBufferInheritanceInfo			inheritanceInfo;
2215 	VkBufferCreateInfo						validNonsenseStructure;
2216 	struct
2217 	{
2218 		VkStructureType	sType;
2219 		void*			pNext;
2220 	} invalidStructure;
2221 
2222 	if (testCase == BadInheritanceInfoCase::RANDOM_PTR || testCase == BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION)
2223 	{
2224 		de::Random						rnd		(1602600778u);
2225 		VkCommandBufferInheritanceInfo*	info;
2226 		auto							ptrData	= reinterpret_cast<deUint8*>(&info);
2227 
2228 		// Fill pointer value with pseudorandom garbage.
2229 		for (size_t i = 0; i < sizeof(info); ++i)
2230 			*ptrData++ = rnd.getUint8();
2231 
2232 		beginInfo.pInheritanceInfo = info;
2233 
2234 		// Try to trick the implementation into reading pInheritanceInfo one more way.
2235 		if (testCase == BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION)
2236 			beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2237 
2238 	}
2239 	else if (testCase == BadInheritanceInfoCase::RANDOM_DATA_PTR)
2240 	{
2241 		de::Random		rnd	(1602601141u);
2242 		auto			itr	= reinterpret_cast<deUint8*>(&inheritanceInfo);
2243 
2244 		// Fill inheritance info data structure with random data.
2245 		for (size_t i = 0; i < sizeof(inheritanceInfo); ++i)
2246 			*itr++ = rnd.getUint8();
2247 
2248 		beginInfo.pInheritanceInfo = &inheritanceInfo;
2249 	}
2250 	else if (testCase == BadInheritanceInfoCase::INVALID_STRUCTURE_TYPE)
2251 	{
2252 		de::Random	rnd			(1602658515u);
2253 		auto		ptrData		= reinterpret_cast<deUint8*>(&(invalidStructure.pNext));
2254 		invalidStructure.sType	= VK_STRUCTURE_TYPE_MAX_ENUM;
2255 
2256 		// Fill pNext pointer with random data.
2257 		for (size_t i = 0; i < sizeof(invalidStructure.pNext); ++i)
2258 			*ptrData++ = rnd.getUint8();
2259 
2260 		beginInfo.pInheritanceInfo = reinterpret_cast<VkCommandBufferInheritanceInfo*>(&invalidStructure);
2261 	}
2262 	else if (testCase == BadInheritanceInfoCase::VALID_NONSENSE_TYPE)
2263 	{
2264 		validNonsenseStructure.sType					= VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2265 		validNonsenseStructure.pNext					= nullptr;
2266 		validNonsenseStructure.flags					= 0u;
2267 		validNonsenseStructure.size						= 1024u;
2268 		validNonsenseStructure.usage					= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2269 		validNonsenseStructure.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
2270 		validNonsenseStructure.queueFamilyIndexCount	= 0u;
2271 		validNonsenseStructure.pQueueFamilyIndices		= nullptr;
2272 
2273 		beginInfo.pInheritanceInfo						= reinterpret_cast<VkCommandBufferInheritanceInfo*>(&validNonsenseStructure);
2274 	}
2275 	else
2276 	{
2277 		DE_ASSERT(false);
2278 	}
2279 
2280 	VK_CHECK(vkd.beginCommandBuffer(cmdBuffer, &beginInfo));
2281 	{
2282 		vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2283 		vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2284 		vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
2285 		vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
2286 							   0, (const VkMemoryBarrier*)DE_NULL,
2287 							   1, &bufferBarrier,
2288 							   0, (const VkImageMemoryBarrier*)DE_NULL);
2289 	}
2290 	endCommandBuffer(vkd, cmdBuffer);
2291 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
2292 
2293 	deUint32 resultCount;
2294 	result.readResultContentsTo(&resultCount);
2295 
2296 	// Make sure the command buffer was run.
2297 	if (resultCount != 1u)
2298 	{
2299 		std::ostringstream msg;
2300 		msg << "Invalid value found in results buffer (expected value 1u but found " << resultCount << ")";
2301 		return tcu::TestStatus::fail(msg.str());
2302 	}
2303 
2304 	return tcu::TestStatus::pass("Pass");
2305 }
2306 
simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context & context)2307 tcu::TestStatus simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context& context)
2308 {
2309 	const VkDevice							vkDevice = context.getDevice();
2310 	const DeviceInterface&					vk = context.getDeviceInterface();
2311 	const VkQueue							queue = context.getUniversalQueue();
2312 	const deUint32							queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2313 	Allocator&								allocator = context.getDefaultAllocator();
2314 	const ComputeInstanceResultBuffer		result(vk, vkDevice, allocator, 0.0f);
2315 
2316 	const VkCommandPoolCreateInfo			cmdPoolParams =
2317 	{
2318 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
2319 		DE_NULL,													//	const void*					pNext;
2320 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
2321 		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
2322 	};
2323 	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2324 
2325 	// Command buffer
2326 	const VkCommandBufferAllocateInfo		cmdBufParams =
2327 	{
2328 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2329 		DE_NULL,													//	const void*				pNext;
2330 		*cmdPool,													//	VkCommandPool				pool;
2331 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
2332 		1u,															//	uint32_t					bufferCount;
2333 	};
2334 	// Two separate primary cmd buffers that will be executed with the same secondary cmd buffer
2335 	const deUint32 numPrimCmdBufs = 2;
2336 	const Unique<VkCommandBuffer>			primCmdBufOne(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2337 	const Unique<VkCommandBuffer>			primCmdBufTwo(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2338 	VkCommandBuffer primCmdBufs[numPrimCmdBufs];
2339 	primCmdBufs[0] = primCmdBufOne.get();
2340 	primCmdBufs[1] = primCmdBufTwo.get();
2341 
2342 	// Secondary Command buffer params
2343 	const VkCommandBufferAllocateInfo		secCmdBufParams =
2344 	{
2345 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
2346 		DE_NULL,													//	const void*				pNext;
2347 		*cmdPool,													//	VkCommandPool				pool;
2348 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
2349 		1u,															//	uint32_t					bufferCount;
2350 	};
2351 	const Unique<VkCommandBuffer>			secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2352 
2353 	const VkCommandBufferBeginInfo			primCmdBufBeginInfo =
2354 	{
2355 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2356 		DE_NULL,
2357 		0,															// flags
2358 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2359 	};
2360 
2361 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo =
2362 	{
2363 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2364 		DE_NULL,
2365 		(VkRenderPass)0u,											// renderPass
2366 		0u,															// subpass
2367 		(VkFramebuffer)0u,											// framebuffer
2368 		VK_FALSE,													// occlusionQueryEnable
2369 		(VkQueryControlFlags)0u,									// queryFlags
2370 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2371 	};
2372 	const VkCommandBufferBeginInfo			secCmdBufBeginInfo =
2373 	{
2374 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2375 		DE_NULL,
2376 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
2377 		&secCmdBufInheritInfo,
2378 	};
2379 
2380 	const deUint32							offset = (0u);
2381 	const deUint32							addressableSize = 256;
2382 	const deUint32							dataSize = 8;
2383 	de::MovePtr<Allocation>					bufferMem;
2384 	const Unique<VkBuffer>					buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2385 	// Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2386 	const Unique<VkDescriptorSetLayout>		descriptorSetLayout(createDescriptorSetLayout(context));
2387 	const Unique<VkDescriptorPool>			descriptorPool(createDescriptorPool(context));
2388 	const Unique<VkDescriptorSet>			descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2389 	const VkDescriptorSet					descriptorSets[] = { *descriptorSet };
2390 	const int								numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2391 
2392 	const VkPipelineLayoutCreateInfo layoutCreateInfo =
2393 	{
2394 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
2395 		DE_NULL,													// pNext
2396 		(VkPipelineLayoutCreateFlags)0,
2397 		numDescriptorSets,											// setLayoutCount
2398 		&descriptorSetLayout.get(),									// pSetLayouts
2399 		0u,															// pushConstantRangeCount
2400 		DE_NULL,													// pPushConstantRanges
2401 	};
2402 	Unique<VkPipelineLayout>				pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2403 
2404 	const Unique<VkShaderModule>			computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2405 
2406 	const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
2407 	{
2408 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2409 		DE_NULL,
2410 		(VkPipelineShaderStageCreateFlags)0,
2411 		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
2412 		*computeModule,												// shader
2413 		"main",
2414 		DE_NULL,													// pSpecializationInfo
2415 	};
2416 
2417 	const VkComputePipelineCreateInfo		pipelineCreateInfo =
2418 	{
2419 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2420 		DE_NULL,
2421 		0u,															// flags
2422 		shaderCreateInfo,											// cs
2423 		*pipelineLayout,											// layout
2424 		(vk::VkPipeline)0,											// basePipelineHandle
2425 		0u,															// basePipelineIndex
2426 	};
2427 
2428 	const Unique<VkPipeline>				pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2429 
2430 	// record secondary command buffer
2431 	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2432 	{
2433 		vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2434 		vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2435 		vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2436 	}
2437 	// end recording of secondary buffer
2438 	endCommandBuffer(vk, *secCmdBuf);
2439 
2440 	// record primary command buffers
2441 	// Insert one instance of same secondary command buffer into two separate primary command buffers
2442 	VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
2443 	{
2444 		vk.cmdExecuteCommands(*primCmdBufOne, 1, &secCmdBuf.get());
2445 	}
2446 	endCommandBuffer(vk, *primCmdBufOne);
2447 
2448 	VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
2449 	{
2450 		vk.cmdExecuteCommands(*primCmdBufTwo, 1, &secCmdBuf.get());
2451 	}
2452 	endCommandBuffer(vk, *primCmdBufTwo);
2453 
2454 	// create fence to wait for execution of queue
2455 	const Unique<VkFence>					fence(createFence(vk, vkDevice));
2456 
2457 	const VkSubmitInfo						submitInfo =
2458 	{
2459 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2460 		DE_NULL,													// pNext
2461 		0u,															// waitSemaphoreCount
2462 		DE_NULL,													// pWaitSemaphores
2463 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2464 		numPrimCmdBufs,												// commandBufferCount
2465 		primCmdBufs,												// pCommandBuffers
2466 		0u,															// signalSemaphoreCount
2467 		DE_NULL,													// pSignalSemaphores
2468 	};
2469 
2470 	// submit primary buffers, the secondary should be executed too
2471 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2472 
2473 	// wait for end of execution of queue
2474 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2475 
2476 	deUint32 resultCount;
2477 	result.readResultContentsTo(&resultCount);
2478 	// check if secondary buffer has been executed
2479 	if (resultCount == 2)
2480 		return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
2481 	else
2482 		return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2483 }
2484 
recordBufferQueryPreciseWithFlagTest(Context & context)2485 tcu::TestStatus recordBufferQueryPreciseWithFlagTest(Context& context)
2486 {
2487 	const VkDevice							vkDevice				= context.getDevice();
2488 	const DeviceInterface&					vk						= context.getDeviceInterface();
2489 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2490 
2491 	if (!context.getDeviceFeatures().inheritedQueries)
2492 		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2493 
2494 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2495 	{
2496 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
2497 		DE_NULL,													// pNext;
2498 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
2499 		queueFamilyIndex,											// queueFamilyIndex;
2500 	};
2501 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2502 
2503 	// Command buffer
2504 	const VkCommandBufferAllocateInfo		primCmdBufParams		=
2505 	{
2506 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2507 		DE_NULL,													// pNext;
2508 		*cmdPool,													// pool;
2509 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
2510 		1u,															// flags;
2511 	};
2512 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2513 
2514 	// Secondary Command buffer params
2515 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
2516 	{
2517 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2518 		DE_NULL,													// pNext;
2519 		*cmdPool,													// pool;
2520 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
2521 		1u,															// flags;
2522 	};
2523 	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2524 
2525 	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
2526 	{
2527 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2528 		DE_NULL,													// pNext
2529 		0u,															// flags
2530 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2531 	};
2532 
2533 	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
2534 	{
2535 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2536 		DE_NULL,
2537 		0u,															// renderPass
2538 		0u,															// subpass
2539 		0u,															// framebuffer
2540 		VK_TRUE,													// occlusionQueryEnable
2541 		VK_QUERY_CONTROL_PRECISE_BIT,								// queryFlags
2542 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2543 	};
2544 	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
2545 	{
2546 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2547 		DE_NULL,													// pNext
2548 		0u,															// flags
2549 		&secBufferInheritInfo,
2550 	};
2551 
2552 	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
2553 	{
2554 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
2555 		DE_NULL,													// pNext
2556 		(VkQueryPoolCreateFlags)0,									// flags
2557 		VK_QUERY_TYPE_OCCLUSION,									// queryType
2558 		1u,															// entryCount
2559 		0u,															// pipelineStatistics
2560 	};
2561 	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2562 
2563 	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2564 	endCommandBuffer(vk, secCmdBuf.get());
2565 
2566 	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2567 	{
2568 		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2569 		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2570 		{
2571 			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2572 		}
2573 		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2574 	}
2575 	endCommandBuffer(vk, primCmdBuf.get());
2576 
2577 	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2578 }
2579 
recordBufferQueryImpreciseWithFlagTest(Context & context)2580 tcu::TestStatus recordBufferQueryImpreciseWithFlagTest(Context& context)
2581 {
2582 	const VkDevice							vkDevice				= context.getDevice();
2583 	const DeviceInterface&					vk						= context.getDeviceInterface();
2584 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2585 
2586 	if (!context.getDeviceFeatures().inheritedQueries)
2587 		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2588 
2589 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2590 	{
2591 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
2592 		DE_NULL,													// pNext;
2593 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
2594 		queueFamilyIndex,											// queueFamilyIndex;
2595 	};
2596 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2597 
2598 	// Command buffer
2599 	const VkCommandBufferAllocateInfo		primCmdBufParams		=
2600 	{
2601 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2602 		DE_NULL,													// pNext;
2603 		*cmdPool,													// pool;
2604 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
2605 		1u,															// flags;
2606 	};
2607 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2608 
2609 	// Secondary Command buffer params
2610 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
2611 	{
2612 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2613 		DE_NULL,													// pNext;
2614 		*cmdPool,													// pool;
2615 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
2616 		1u,															// flags;
2617 	};
2618 	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2619 
2620 	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
2621 	{
2622 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2623 		DE_NULL,													// pNext
2624 		0u,															// flags
2625 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2626 	};
2627 
2628 	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
2629 	{
2630 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2631 		DE_NULL,
2632 		0u,															// renderPass
2633 		0u,															// subpass
2634 		0u,															// framebuffer
2635 		VK_TRUE,													// occlusionQueryEnable
2636 		VK_QUERY_CONTROL_PRECISE_BIT,								// queryFlags
2637 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2638 	};
2639 	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
2640 	{
2641 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2642 		DE_NULL,													// pNext
2643 		0u,															// flags
2644 		&secBufferInheritInfo,
2645 	};
2646 
2647 	// Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
2648 	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
2649 	{
2650 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
2651 		DE_NULL,													// pNext
2652 		0u,															// flags
2653 		VK_QUERY_TYPE_OCCLUSION,									// queryType
2654 		1u,															// entryCount
2655 		0u,															// pipelineStatistics
2656 	};
2657 	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2658 
2659 	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2660 	endCommandBuffer(vk, secCmdBuf.get());
2661 
2662 	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2663 	{
2664 		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2665 		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2666 		{
2667 			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2668 		}
2669 		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2670 	}
2671 	endCommandBuffer(vk, primCmdBuf.get());
2672 
2673 	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2674 }
2675 
recordBufferQueryImpreciseWithoutFlagTest(Context & context)2676 tcu::TestStatus recordBufferQueryImpreciseWithoutFlagTest(Context& context)
2677 {
2678 	const VkDevice							vkDevice				= context.getDevice();
2679 	const DeviceInterface&					vk						= context.getDeviceInterface();
2680 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2681 
2682 	if (!context.getDeviceFeatures().inheritedQueries)
2683 		TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2684 
2685 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2686 	{
2687 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
2688 		DE_NULL,													// pNext;
2689 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
2690 		queueFamilyIndex,											// queueFamilyIndex;
2691 	};
2692 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2693 
2694 	// Command buffer
2695 	const VkCommandBufferAllocateInfo		primCmdBufParams		=
2696 	{
2697 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2698 		DE_NULL,													// pNext;
2699 		*cmdPool,													// pool;
2700 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
2701 		1u,															// flags;
2702 	};
2703 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2704 
2705 	// Secondary Command buffer params
2706 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
2707 	{
2708 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2709 		DE_NULL,													// pNext;
2710 		*cmdPool,													// pool;
2711 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
2712 		1u,															// flags;
2713 	};
2714 	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2715 
2716 	const VkCommandBufferBeginInfo			primBufferBeginInfo		=
2717 	{
2718 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2719 		DE_NULL,													// pNext
2720 		0u,															// flags
2721 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2722 	};
2723 
2724 	const VkCommandBufferInheritanceInfo	secBufferInheritInfo	=
2725 	{
2726 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2727 		DE_NULL,
2728 		0u,															// renderPass
2729 		0u,															// subpass
2730 		0u,															// framebuffer
2731 		VK_TRUE,													// occlusionQueryEnable
2732 		0u,															// queryFlags
2733 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
2734 	};
2735 	const VkCommandBufferBeginInfo			secBufferBeginInfo		=
2736 	{
2737 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2738 		DE_NULL,													// pNext
2739 		0u,															// flags
2740 		&secBufferInheritInfo,
2741 	};
2742 
2743 	// Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
2744 	const VkQueryPoolCreateInfo				queryPoolCreateInfo		=
2745 	{
2746 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,					// sType
2747 		DE_NULL,													// pNext
2748 		(VkQueryPoolCreateFlags)0,
2749 		VK_QUERY_TYPE_OCCLUSION,
2750 		1u,
2751 		0u,
2752 	};
2753 	Unique<VkQueryPool>						queryPool				(createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2754 
2755 	VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2756 	endCommandBuffer(vk, secCmdBuf.get());
2757 
2758 	VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2759 	{
2760 		vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2761 		vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2762 		{
2763 			vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2764 		}
2765 		vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2766 	}
2767 	endCommandBuffer(vk, primCmdBuf.get());
2768 
2769 	return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2770 }
2771 
2772 /******** 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) ****************/
submitBufferCountNonZero(Context & context)2773 tcu::TestStatus submitBufferCountNonZero(Context& context)
2774 {
2775 	const VkDevice							vkDevice				= context.getDevice();
2776 	const DeviceInterface&					vk						= context.getDeviceInterface();
2777 	const VkQueue							queue					= context.getUniversalQueue();
2778 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2779 
2780 	const deUint32							BUFFER_COUNT			= 5u;
2781 
2782 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2783 	{
2784 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
2785 		DE_NULL,													// pNext;
2786 		0u,															// flags;
2787 		queueFamilyIndex,											// queueFamilyIndex;
2788 	};
2789 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2790 
2791 	// Command buffer
2792 	const VkCommandBufferAllocateInfo		cmdBufParams			=
2793 	{
2794 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2795 		DE_NULL,													// pNext;
2796 		*cmdPool,													// pool;
2797 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
2798 		BUFFER_COUNT,												// bufferCount;
2799 	};
2800 	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2801 	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2802 
2803 	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
2804 	{
2805 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2806 		DE_NULL,													// pNext
2807 		0u,															// flags
2808 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2809 	};
2810 
2811 	std::vector<VkEventSp>					events;
2812 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2813 	{
2814 		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
2815 	}
2816 
2817 	// Record the command buffers
2818 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2819 	{
2820 		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2821 		{
2822 			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2823 		}
2824 		endCommandBuffer(vk, cmdBuffers[ndx]);
2825 	}
2826 
2827 	// We'll use a fence to wait for the execution of the queue
2828 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
2829 
2830 	const VkSubmitInfo						submitInfo				=
2831 	{
2832 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2833 		DE_NULL,													// pNext
2834 		0u,															// waitSemaphoreCount
2835 		DE_NULL,													// pWaitSemaphores
2836 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2837 		BUFFER_COUNT,												// commandBufferCount
2838 		cmdBuffers,													// pCommandBuffers
2839 		0u,															// signalSemaphoreCount
2840 		DE_NULL,													// pSignalSemaphores
2841 	};
2842 
2843 	// Submit the alpha command buffer to the queue
2844 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
2845 	// Wait for the queue
2846 	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
2847 
2848 	// Check if the buffers were executed
2849 	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
2850 
2851 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2852 	{
2853 		if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
2854 		{
2855 			testResult = tcu::TestStatus::fail("Failed to set the event.");
2856 			break;
2857 		}
2858 	}
2859 
2860 	if (!testResult.isComplete())
2861 		testResult = tcu::TestStatus::pass("All buffers were submitted and executed correctly.");
2862 
2863 	return testResult;
2864 }
2865 
submitBufferCountEqualZero(Context & context)2866 tcu::TestStatus submitBufferCountEqualZero(Context& context)
2867 {
2868 	const VkDevice							vkDevice				= context.getDevice();
2869 	const DeviceInterface&					vk						= context.getDeviceInterface();
2870 	const VkQueue							queue					= context.getUniversalQueue();
2871 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2872 
2873 	const deUint32							BUFFER_COUNT			= 2u;
2874 
2875 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2876 	{
2877 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
2878 		DE_NULL,													// pNext;
2879 		0u,															// flags;
2880 		queueFamilyIndex,											// queueFamilyIndex;
2881 	};
2882 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2883 
2884 	// Command buffer
2885 	const VkCommandBufferAllocateInfo		cmdBufParams			=
2886 	{
2887 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
2888 		DE_NULL,													// pNext;
2889 		*cmdPool,													// pool;
2890 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
2891 		BUFFER_COUNT,												// bufferCount;
2892 	};
2893 	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2894 	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2895 
2896 	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
2897 	{
2898 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
2899 		DE_NULL,													// pNext
2900 		0u,															// flags
2901 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2902 	};
2903 
2904 	std::vector<VkEventSp>					events;
2905 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2906 		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
2907 
2908 	// Record the command buffers
2909 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2910 	{
2911 		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2912 		{
2913 			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2914 		}
2915 		endCommandBuffer(vk, cmdBuffers[ndx]);
2916 	}
2917 
2918 	// We'll use a fence to wait for the execution of the queue
2919 	const Unique<VkFence>					fenceZero				(createFence(vk, vkDevice));
2920 	const Unique<VkFence>					fenceOne				(createFence(vk, vkDevice));
2921 
2922 	const VkSubmitInfo						submitInfoCountZero		=
2923 	{
2924 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2925 		DE_NULL,													// pNext
2926 		0u,															// waitSemaphoreCount
2927 		DE_NULL,													// pWaitSemaphores
2928 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2929 		1u,															// commandBufferCount
2930 		&cmdBuffers[0],												// pCommandBuffers
2931 		0u,															// signalSemaphoreCount
2932 		DE_NULL,													// pSignalSemaphores
2933 	};
2934 
2935 	const VkSubmitInfo						submitInfoCountOne		=
2936 	{
2937 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
2938 		DE_NULL,													// pNext
2939 		0u,															// waitSemaphoreCount
2940 		DE_NULL,													// pWaitSemaphores
2941 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
2942 		1u,															// commandBufferCount
2943 		&cmdBuffers[1],												// pCommandBuffers
2944 		0u,															// signalSemaphoreCount
2945 		DE_NULL,													// pSignalSemaphores
2946 	};
2947 
2948 	// Submit the command buffers to the queue
2949 	// We're performing two submits to make sure that the first one has
2950 	// a chance to be processed before we check the event's status
2951 	VK_CHECK(vk.queueSubmit(queue, 0, &submitInfoCountZero, fenceZero.get()));
2952 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfoCountOne, fenceOne.get()));
2953 
2954 	const VkFence							fences[]				=
2955 	{
2956 		fenceZero.get(),
2957 		fenceOne.get(),
2958 	};
2959 
2960 	// Wait for the queue
2961 	VK_CHECK(vk.waitForFences(vkDevice, (deUint32)DE_LENGTH_OF_ARRAY(fences), fences, VK_TRUE, INFINITE_TIMEOUT));
2962 
2963 	// Check if the first buffer was executed
2964 	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
2965 
2966 	if (vk.getEventStatus(vkDevice, events[0]->get()) == VK_EVENT_SET)
2967 		testResult = tcu::TestStatus::fail("The first event was signaled.");
2968 	else
2969 		testResult = tcu::TestStatus::pass("The first submission was ignored.");
2970 
2971 	return testResult;
2972 }
2973 
submitBufferWaitSingleSemaphore(Context & context)2974 tcu::TestStatus submitBufferWaitSingleSemaphore(Context& context)
2975 {
2976 	const VkDevice							vkDevice				= context.getDevice();
2977 	const DeviceInterface&					vk						= context.getDeviceInterface();
2978 	const VkQueue							queue					= context.getUniversalQueue();
2979 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2980 
2981 	const VkCommandPoolCreateInfo			cmdPoolParams			=
2982 	{
2983 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// VkStructureType				sType;
2984 		DE_NULL,													// const void*					pNext;
2985 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// VkCommandPoolCreateFlags		flags;
2986 		queueFamilyIndex,											// deUint32						queueFamilyIndex;
2987 	};
2988 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
2989 
2990 	// Command buffer
2991 	const VkCommandBufferAllocateInfo		cmdBufParams			=
2992 	{
2993 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType				sType;
2994 		DE_NULL,													// const void*					pNext;
2995 		*cmdPool,													// VkCommandPool				pool;
2996 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// VkCommandBufferLevel			level;
2997 		1u,															// uint32_t						bufferCount;
2998 	};
2999 
3000 	// Create two command buffers
3001 	const Unique<VkCommandBuffer>			primCmdBuf1				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3002 	const Unique<VkCommandBuffer>			primCmdBuf2				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3003 
3004 	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3005 	{
3006 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3007 		DE_NULL,													// pNext
3008 		0,															// flags
3009 		DE_NULL														// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
3010 	};
3011 
3012 	// create two events that will be used to check if command buffers has been executed
3013 	const Unique<VkEvent>					event1					(createEvent(vk, vkDevice));
3014 	const Unique<VkEvent>					event2					(createEvent(vk, vkDevice));
3015 
3016 	// reset events
3017 	VK_CHECK(vk.resetEvent(vkDevice, *event1));
3018 	VK_CHECK(vk.resetEvent(vkDevice, *event2));
3019 
3020 	// record first command buffer
3021 	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
3022 	{
3023 		// allow execution of event during every stage of pipeline
3024 		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3025 
3026 		// record setting event
3027 		vk.cmdSetEvent(*primCmdBuf1, *event1,stageMask);
3028 	}
3029 	endCommandBuffer(vk, *primCmdBuf1);
3030 
3031 	// record second command buffer
3032 	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
3033 	{
3034 		// allow execution of event during every stage of pipeline
3035 		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3036 
3037 		// record setting event
3038 		vk.cmdSetEvent(*primCmdBuf2, *event2,stageMask);
3039 	}
3040 	endCommandBuffer(vk, *primCmdBuf2);
3041 
3042 	// create fence to wait for execution of queue
3043 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
3044 
3045 	// create semaphore for use in this test
3046 	const Unique <VkSemaphore>				semaphore				(createSemaphore(vk, vkDevice));
3047 
3048 	// create submit info for first buffer - signalling semaphore
3049 	const VkSubmitInfo						submitInfo1				=
3050 	{
3051 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3052 		DE_NULL,													// pNext
3053 		0u,															// waitSemaphoreCount
3054 		DE_NULL,													// pWaitSemaphores
3055 		DE_NULL,													// pWaitDstStageMask
3056 		1,															// commandBufferCount
3057 		&primCmdBuf1.get(),											// pCommandBuffers
3058 		1u,															// signalSemaphoreCount
3059 		&semaphore.get(),											// pSignalSemaphores
3060 	};
3061 
3062 	// Submit the command buffer to the queue
3063 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3064 
3065 	// wait for end of execution of queue
3066 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3067 
3068 	// check if buffer has been executed
3069 	VkResult result = vk.getEventStatus(vkDevice,*event1);
3070 	if (result != VK_EVENT_SET)
3071 		return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3072 
3073 	const VkPipelineStageFlags				waitDstStageFlags		= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3074 
3075 	// create submit info for second buffer - waiting for semaphore
3076 	const VkSubmitInfo						submitInfo2				=
3077 	{
3078 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3079 		DE_NULL,													// pNext
3080 		1u,															// waitSemaphoreCount
3081 		&semaphore.get(),											// pWaitSemaphores
3082 		&waitDstStageFlags,											// pWaitDstStageMask
3083 		1,															// commandBufferCount
3084 		&primCmdBuf2.get(),											// pCommandBuffers
3085 		0u,															// signalSemaphoreCount
3086 		DE_NULL,													// pSignalSemaphores
3087 	};
3088 
3089 	// reset fence, so it can be used again
3090 	VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3091 
3092 	// Submit the second command buffer to the queue
3093 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3094 
3095 	// wait for end of execution of queue
3096 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3097 
3098 	// check if second buffer has been executed
3099 	// if it has been executed, it means that the semaphore was signalled - so test if passed
3100 	result = vk.getEventStatus(vkDevice,*event1);
3101 	if (result != VK_EVENT_SET)
3102 		return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3103 
3104 	return tcu::TestStatus::pass("Submit Buffer and Wait for Single Semaphore Test succeeded");
3105 }
3106 
submitBufferWaitManySemaphores(Context & context)3107 tcu::TestStatus submitBufferWaitManySemaphores(Context& context)
3108 {
3109 	// This test will create numSemaphores semaphores, and signal them in NUM_SEMAPHORES submits to queue
3110 	// After that the numSubmissions queue submissions will wait for each semaphore
3111 
3112 	const deUint32							numSemaphores			= 10u;  // it must be multiply of numSubmission
3113 	const deUint32							numSubmissions			= 2u;
3114 	const VkDevice							vkDevice				= context.getDevice();
3115 	const DeviceInterface&					vk						= context.getDeviceInterface();
3116 	const VkQueue							queue					= context.getUniversalQueue();
3117 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3118 
3119 	const VkCommandPoolCreateInfo			cmdPoolParams			=
3120 	{
3121 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// VkStructureType				sType;
3122 		DE_NULL,													// const void*					pNext;
3123 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// VkCommandPoolCreateFlags		flags;
3124 		queueFamilyIndex,											// deUint32						queueFamilyIndex;
3125 	};
3126 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3127 
3128 	// Command buffer
3129 	const VkCommandBufferAllocateInfo		cmdBufParams			=
3130 	{
3131 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// VkStructureType				sType;
3132 		DE_NULL,													// const void*					pNext;
3133 		*cmdPool,													// VkCommandPool				pool;
3134 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// VkCommandBufferLevel			level;
3135 		1u,															// uint32_t						bufferCount;
3136 	};
3137 
3138 	// Create command buffer
3139 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3140 
3141 	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3142 	{
3143 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3144 		DE_NULL,													// pNext
3145 		0,															// flags
3146 		DE_NULL														// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
3147 	};
3148 
3149 	// create event that will be used to check if command buffers has been executed
3150 	const Unique<VkEvent>					event					(createEvent(vk, vkDevice));
3151 
3152 	// reset event - at creation state is undefined
3153 	VK_CHECK(vk.resetEvent(vkDevice, *event));
3154 
3155 	// record command buffer
3156 	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3157 	{
3158 		// allow execution of event during every stage of pipeline
3159 		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3160 
3161 		// record setting event
3162 		vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
3163 	}
3164 	endCommandBuffer(vk, *primCmdBuf);
3165 
3166 	// create fence to wait for execution of queue
3167 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
3168 
3169 	// numSemaphores is declared const, so this array can be static
3170 	// the semaphores will be destroyed automatically at end of scope
3171 	Move <VkSemaphore>						semaphoreArray[numSemaphores];
3172 	VkSemaphore								semaphores[numSemaphores];
3173 
3174 	for (deUint32 idx = 0; idx < numSemaphores; ++idx) {
3175 		// create semaphores for use in this test
3176 		semaphoreArray[idx] = createSemaphore(vk, vkDevice);
3177 		semaphores[idx] = semaphoreArray[idx].get();
3178 	}
3179 
3180 	{
3181 		// create submit info for buffer - signal semaphores
3182 		const VkSubmitInfo submitInfo1 =
3183 		{
3184 			VK_STRUCTURE_TYPE_SUBMIT_INFO,							// sType
3185 			DE_NULL,												// pNext
3186 			0u,														// waitSemaphoreCount
3187 			DE_NULL,												// pWaitSemaphores
3188 			DE_NULL,												// pWaitDstStageMask
3189 			1,														// commandBufferCount
3190 			&primCmdBuf.get(),										// pCommandBuffers
3191 			numSemaphores,											// signalSemaphoreCount
3192 			semaphores												// pSignalSemaphores
3193 		};
3194 		// Submit the command buffer to the queue
3195 		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3196 
3197 		// wait for end of execution of queue
3198 		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3199 
3200 		// check if buffer has been executed
3201 		VkResult result = vk.getEventStatus(vkDevice,*event);
3202 		if (result != VK_EVENT_SET)
3203 			return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3204 
3205 		// reset event, so next buffers can set it again
3206 		VK_CHECK(vk.resetEvent(vkDevice, *event));
3207 
3208 		// reset fence, so it can be used again
3209 		VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3210 	}
3211 
3212 	const deUint32							numberOfSemaphoresToBeWaitedByOneSubmission	= numSemaphores / numSubmissions;
3213 	const std::vector<VkPipelineStageFlags>	waitDstStageFlags							(numberOfSemaphoresToBeWaitedByOneSubmission, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
3214 
3215 	// the following code waits for the semaphores set above - numSubmissions queues will wait for each semaphore from above
3216 	for (deUint32 idxSubmission = 0; idxSubmission < numSubmissions; ++idxSubmission) {
3217 
3218 		// create submit info for buffer - waiting for semaphore
3219 		const VkSubmitInfo				submitInfo2				=
3220 		{
3221 			VK_STRUCTURE_TYPE_SUBMIT_INFO,												// sType
3222 			DE_NULL,																	// pNext
3223 			numberOfSemaphoresToBeWaitedByOneSubmission,								// waitSemaphoreCount
3224 			semaphores + (numberOfSemaphoresToBeWaitedByOneSubmission * idxSubmission),	// pWaitSemaphores
3225 			waitDstStageFlags.data(),													// pWaitDstStageMask
3226 			1,																			// commandBufferCount
3227 			&primCmdBuf.get(),															// pCommandBuffers
3228 			0u,																			// signalSemaphoreCount
3229 			DE_NULL,																	// pSignalSemaphores
3230 		};
3231 
3232 		// Submit the second command buffer to the queue
3233 		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3234 
3235 		// wait for 1 second.
3236 		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 1000 * 1000 * 1000));
3237 
3238 		// check if second buffer has been executed
3239 		// if it has been executed, it means that the semaphore was signalled - so test if passed
3240 		VkResult result = vk.getEventStatus(vkDevice,*event);
3241 		if (result != VK_EVENT_SET)
3242 			return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3243 
3244 		// reset fence, so it can be used again
3245 		VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3246 
3247 		// reset event, so next buffers can set it again
3248 		VK_CHECK(vk.resetEvent(vkDevice, *event));
3249 	}
3250 
3251 	return tcu::TestStatus::pass("Submit Buffer and Wait for Many Semaphores Test succeeded");
3252 }
3253 
submitBufferNullFence(Context & context)3254 tcu::TestStatus submitBufferNullFence(Context& context)
3255 {
3256 	const VkDevice							vkDevice				= context.getDevice();
3257 	const DeviceInterface&					vk						= context.getDeviceInterface();
3258 	const VkQueue							queue					= context.getUniversalQueue();
3259 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3260 
3261 	const short								BUFFER_COUNT			= 2;
3262 
3263 	const VkCommandPoolCreateInfo			cmdPoolParams			=
3264 	{
3265 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3266 		DE_NULL,													// pNext;
3267 		0u,															// flags;
3268 		queueFamilyIndex,											// queueFamilyIndex;
3269 	};
3270 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3271 
3272 	// Command buffer
3273 	const VkCommandBufferAllocateInfo		cmdBufParams			=
3274 	{
3275 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3276 		DE_NULL,													// pNext;
3277 		*cmdPool,													// pool;
3278 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3279 		1u,															// bufferCount;
3280 	};
3281 	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3282 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3283 		VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffers[ndx]));
3284 
3285 	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3286 	{
3287 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3288 		DE_NULL,													// pNext
3289 		0u,															// flags
3290 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3291 	};
3292 
3293 	std::vector<VkEventSp>					events;
3294 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3295 		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
3296 
3297 	// Record the command buffers
3298 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3299 	{
3300 		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3301 		{
3302 			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3303 		}
3304 		endCommandBuffer(vk, cmdBuffers[ndx]);
3305 	}
3306 
3307 	// We'll use a fence to wait for the execution of the queue
3308 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
3309 
3310 	const VkSubmitInfo						submitInfoNullFence		=
3311 	{
3312 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3313 		DE_NULL,													// pNext
3314 		0u,															// waitSemaphoreCount
3315 		DE_NULL,													// pWaitSemaphores
3316 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3317 		1u,															// commandBufferCount
3318 		&cmdBuffers[0],												// pCommandBuffers
3319 		0u,															// signalSemaphoreCount
3320 		DE_NULL,													// pSignalSemaphores
3321 	};
3322 
3323 	const VkSubmitInfo						submitInfoNonNullFence	=
3324 	{
3325 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3326 		DE_NULL,													// pNext
3327 		0u,															// waitSemaphoreCount
3328 		DE_NULL,													// pWaitSemaphores
3329 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3330 		1u,															// commandBufferCount
3331 		&cmdBuffers[1],												// pCommandBuffers
3332 		0u,															// signalSemaphoreCount
3333 		DE_NULL,													// pSignalSemaphores
3334 	};
3335 
3336 	// Perform two submissions - one with no fence, the other one with a valid
3337 	// fence Hoping submitting the other buffer will give the first one time to
3338 	// execute
3339 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNullFence, DE_NULL));
3340 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNonNullFence, fence.get()));
3341 
3342 	// Wait for the queue
3343 	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3344 
3345 
3346 	tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3347 
3348 	//Fence guaranteed that all buffers submited before fence were executed
3349 	if (vk.getEventStatus(vkDevice, events[0]->get()) != VK_EVENT_SET || vk.getEventStatus(vkDevice, events[1]->get()) != VK_EVENT_SET)
3350 	{
3351 		testResult = tcu::TestStatus::fail("One of the buffers was not executed.");
3352 	}
3353 	else
3354 	{
3355 		testResult = tcu::TestStatus::pass("Buffers have been submitted and executed correctly.");
3356 	}
3357 
3358 	vk.queueWaitIdle(queue);
3359 	return testResult;
3360 }
3361 
submitTwoBuffersOneBufferNullWithFence(Context & context)3362 tcu::TestStatus submitTwoBuffersOneBufferNullWithFence(Context& context)
3363 {
3364 	const VkDevice							vkDevice				= context.getDevice();
3365 	const DeviceInterface&					vk						= context.getDeviceInterface();
3366 	const VkQueue							queue					= context.getUniversalQueue();
3367 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3368 	const deUint32							BUFFER_COUNT			= 2u;
3369 
3370 	const VkCommandPoolCreateInfo			cmdPoolParams			=
3371 	{
3372 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// sType;
3373 		DE_NULL,											// pNext;
3374 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// flags;
3375 		queueFamilyIndex,									// queueFamilyIndex;
3376 	};
3377 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3378 
3379 	const VkCommandBufferAllocateInfo		cmdBufParams			=
3380 	{
3381 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// sType;
3382 		DE_NULL,										// pNext;
3383 		*cmdPool,										// pool;
3384 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// level;
3385 		BUFFER_COUNT,									// bufferCount;
3386 	};
3387 
3388 	VkCommandBuffer							cmdBuffers[BUFFER_COUNT];
3389 	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
3390 
3391 	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3392 	{
3393 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// sType
3394 		DE_NULL,										// pNext
3395 		0u,												// flags
3396 		(const VkCommandBufferInheritanceInfo*)DE_NULL,	// pInheritanceInfo
3397 	};
3398 
3399 	std::vector<VkEventSp>					events;
3400 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3401 		events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
3402 
3403 	// Record the command buffers
3404 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3405 	{
3406 		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3407 		{
3408 			vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3409 		}
3410 		VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3411 	}
3412 
3413 	// First command buffer
3414 	const VkSubmitInfo						submitInfoNonNullFirst	=
3415 	{
3416 		VK_STRUCTURE_TYPE_SUBMIT_INFO,				// sType
3417 		DE_NULL,									// pNext
3418 		0u,											// waitSemaphoreCount
3419 		DE_NULL,									// pWaitSemaphores
3420 		(const VkPipelineStageFlags*)DE_NULL,		// pWaitDstStageMask
3421 		1u,											// commandBufferCount
3422 		&cmdBuffers[0],								// pCommandBuffers
3423 		0u,											// signalSemaphoreCount
3424 		DE_NULL,									// pSignalSemaphores
3425 	};
3426 
3427 	// Second command buffer
3428 	const VkSubmitInfo						submitInfoNonNullSecond	=
3429 	{
3430 		VK_STRUCTURE_TYPE_SUBMIT_INFO,				// sType
3431 		DE_NULL,									// pNext
3432 		0u,											// waitSemaphoreCount
3433 		DE_NULL,									// pWaitSemaphores
3434 		(const VkPipelineStageFlags*)DE_NULL,		// pWaitDstStageMask
3435 		1u,											// commandBufferCount
3436 		&cmdBuffers[1],								// pCommandBuffers
3437 		0u,											// signalSemaphoreCount
3438 		DE_NULL,									// pSignalSemaphores
3439 	};
3440 
3441 	// Fence will be submitted with the null queue
3442 	const Unique<VkFence>					fence					(createFence(vk, vkDevice));
3443 
3444 	// Perform two separate queueSubmit calls on the same queue followed
3445 	// by a third call with no submitInfos and with a valid fence
3446 	VK_CHECK(vk.queueSubmit(queue,	1u,	&submitInfoNonNullFirst,	DE_NULL));
3447 	VK_CHECK(vk.queueSubmit(queue,	1u,	&submitInfoNonNullSecond,	DE_NULL));
3448 	VK_CHECK(vk.queueSubmit(queue,	0u,	DE_NULL,					fence.get()));
3449 
3450 	// Wait for the queue
3451 	VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3452 
3453 	return tcu::TestStatus::pass("Buffers have been submitted correctly");
3454 }
3455 
3456 /******** 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) *******/
executeSecondaryBufferTest(Context & context)3457 tcu::TestStatus executeSecondaryBufferTest(Context& context)
3458 {
3459 	const VkDevice							vkDevice				= context.getDevice();
3460 	const DeviceInterface&					vk						= context.getDeviceInterface();
3461 	const VkQueue							queue					= context.getUniversalQueue();
3462 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3463 
3464 	const VkCommandPoolCreateInfo			cmdPoolParams			=
3465 	{
3466 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3467 		DE_NULL,													// pNext;
3468 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags;
3469 		queueFamilyIndex,											// queueFamilyIndex;
3470 	};
3471 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3472 
3473 	// Command buffer
3474 	const VkCommandBufferAllocateInfo		cmdBufParams			=
3475 	{
3476 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3477 		DE_NULL,													// pNext;
3478 		*cmdPool,													// commandPool;
3479 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level;
3480 		1u,															// bufferCount;
3481 	};
3482 	const Unique<VkCommandBuffer>			primCmdBuf				(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3483 
3484 	// Secondary Command buffer
3485 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
3486 	{
3487 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType;
3488 		DE_NULL,													// pNext;
3489 		*cmdPool,													// commandPool;
3490 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							// level;
3491 		1u,															// bufferCount;
3492 	};
3493 	const Unique<VkCommandBuffer>			secCmdBuf				(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3494 
3495 	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3496 	{
3497 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3498 		DE_NULL,													// pNext
3499 		0u,															// flags
3500 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3501 	};
3502 
3503 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
3504 	{
3505 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3506 		DE_NULL,
3507 		DE_NULL,													// renderPass
3508 		0u,															// subpass
3509 		DE_NULL,													// framebuffer
3510 		VK_FALSE,													// occlusionQueryEnable
3511 		(VkQueryControlFlags)0u,									// queryFlags
3512 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
3513 	};
3514 	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
3515 	{
3516 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3517 		DE_NULL,													// pNext
3518 		0u,															// flags
3519 		&secCmdBufInheritInfo,
3520 	};
3521 
3522 	// create event that will be used to check if secondary command buffer has been executed
3523 	const Unique<VkEvent>					event					(createEvent(vk, vkDevice));
3524 
3525 	// reset event
3526 	VK_CHECK(vk.resetEvent(vkDevice, *event));
3527 
3528 	// record secondary command buffer
3529 	VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
3530 	{
3531 		// allow execution of event during every stage of pipeline
3532 		VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3533 		// record setting event
3534 		vk.cmdSetEvent(*secCmdBuf, *event, stageMask);
3535 	}
3536 	// end recording of the secondary buffer
3537 	endCommandBuffer(vk, *secCmdBuf);
3538 
3539 	// record primary command buffer
3540 	VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3541 	{
3542 		// execute secondary buffer
3543 		vk.cmdExecuteCommands(*primCmdBuf, 1u, &secCmdBuf.get());
3544 	}
3545 	endCommandBuffer(vk, *primCmdBuf);
3546 
3547 	submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
3548 
3549 	// check if secondary buffer has been executed
3550 	VkResult result = vk.getEventStatus(vkDevice, *event);
3551 	if (result == VK_EVENT_SET)
3552 		return tcu::TestStatus::pass("executeSecondaryBufferTest succeeded");
3553 
3554 	return tcu::TestStatus::fail("executeSecondaryBufferTest FAILED");
3555 }
3556 
executeSecondaryBufferTwiceTest(Context & context)3557 tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context)
3558 {
3559 	const deUint32							BUFFER_COUNT			= 10u;
3560 	const VkDevice							vkDevice				= context.getDevice();
3561 	const DeviceInterface&					vk						= context.getDeviceInterface();
3562 	const VkQueue							queue					= context.getUniversalQueue();
3563 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3564 
3565 	const VkCommandPoolCreateInfo			cmdPoolParams			=
3566 	{
3567 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					//	VkStructureType				sType;
3568 		DE_NULL,													//	const void*					pNext;
3569 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			//	VkCommandPoolCreateFlags	flags;
3570 		queueFamilyIndex,											//	deUint32					queueFamilyIndex;
3571 	};
3572 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
3573 
3574 	// Command buffer
3575 	const VkCommandBufferAllocateInfo		cmdBufParams			=
3576 	{
3577 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
3578 		DE_NULL,													//	const void*				pNext;
3579 		*cmdPool,													//	VkCommandPool				pool;
3580 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							//	VkCommandBufferLevel		level;
3581 		1u,															//	uint32_t					bufferCount;
3582 	};
3583 	const Unique<VkCommandBuffer>			primCmdBufOne			(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3584 	const Unique<VkCommandBuffer>			primCmdBufTwo			(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3585 
3586 	// Secondary Command buffers params
3587 	const VkCommandBufferAllocateInfo		secCmdBufParams			=
3588 	{
3589 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				//	VkStructureType			sType;
3590 		DE_NULL,													//	const void*				pNext;
3591 		*cmdPool,													//	VkCommandPool				pool;
3592 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,							//	VkCommandBufferLevel		level;
3593 		BUFFER_COUNT,												//	uint32_t					bufferCount;
3594 	};
3595 	VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3596 	VK_CHECK(vk.allocateCommandBuffers(vkDevice, &secCmdBufParams, cmdBuffers));
3597 
3598 	const VkCommandBufferBeginInfo			primCmdBufBeginInfo		=
3599 	{
3600 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3601 		DE_NULL,
3602 		0,															// flags
3603 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3604 	};
3605 
3606 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
3607 	{
3608 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3609 		DE_NULL,
3610 		(VkRenderPass)0u,											// renderPass
3611 		0u,															// subpass
3612 		(VkFramebuffer)0u,											// framebuffer
3613 		VK_FALSE,													// occlusionQueryEnable
3614 		(VkQueryControlFlags)0u,									// queryFlags
3615 		(VkQueryPipelineStatisticFlags)0u,							// pipelineStatistics
3616 	};
3617 	const VkCommandBufferBeginInfo			secCmdBufBeginInfo		=
3618 	{
3619 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3620 		DE_NULL,
3621 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,				// flags
3622 		&secCmdBufInheritInfo,
3623 	};
3624 
3625 	// create event that will be used to check if secondary command buffer has been executed
3626 	const Unique<VkEvent>					eventOne				(createEvent(vk, vkDevice));
3627 
3628 	// reset event
3629 	VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
3630 
3631 	for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3632 	{
3633 		// record secondary command buffer
3634 		VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo));
3635 		{
3636 			// allow execution of event during every stage of pipeline
3637 			VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3638 
3639 			// wait for event
3640 			vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
3641 		}
3642 		// end recording of secondary buffers
3643 		endCommandBuffer(vk, cmdBuffers[ndx]);
3644 	}
3645 
3646 	// record primary command buffer one
3647 	VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
3648 	{
3649 		// execute one secondary buffer
3650 		vk.cmdExecuteCommands(*primCmdBufOne, 1, cmdBuffers );
3651 	}
3652 	endCommandBuffer(vk, *primCmdBufOne);
3653 
3654 	// record primary command buffer two
3655 	VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
3656 	{
3657 		// execute one secondary buffer with all buffers
3658 		vk.cmdExecuteCommands(*primCmdBufTwo, BUFFER_COUNT, cmdBuffers );
3659 	}
3660 	endCommandBuffer(vk, *primCmdBufTwo);
3661 
3662 	// create fence to wait for execution of queue
3663 	const Unique<VkFence>					fenceOne				(createFence(vk, vkDevice));
3664 	const Unique<VkFence>					fenceTwo				(createFence(vk, vkDevice));
3665 
3666 	const VkSubmitInfo						submitInfoOne			=
3667 	{
3668 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3669 		DE_NULL,													// pNext
3670 		0u,															// waitSemaphoreCount
3671 		DE_NULL,													// pWaitSemaphores
3672 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3673 		1,															// commandBufferCount
3674 		&primCmdBufOne.get(),										// pCommandBuffers
3675 		0u,															// signalSemaphoreCount
3676 		DE_NULL,													// pSignalSemaphores
3677 	};
3678 
3679 	// submit primary buffer, the secondary should be executed too
3680 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne));
3681 
3682 	// wait for buffer to stop at event for 100 microseconds
3683 	vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3684 
3685 	const VkSubmitInfo						submitInfoTwo			=
3686 	{
3687 		VK_STRUCTURE_TYPE_SUBMIT_INFO,								// sType
3688 		DE_NULL,													// pNext
3689 		0u,															// waitSemaphoreCount
3690 		DE_NULL,													// pWaitSemaphores
3691 		(const VkPipelineStageFlags*)DE_NULL,						// pWaitDstStageMask
3692 		1,															// commandBufferCount
3693 		&primCmdBufTwo.get(),										// pCommandBuffers
3694 		0u,															// signalSemaphoreCount
3695 		DE_NULL,													// pSignalSemaphores
3696 	};
3697 
3698 	// submit second primary buffer, the secondary should be executed too
3699 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo));
3700 
3701 	// wait for all buffers to stop at event for 100 microseconds
3702 	vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3703 
3704 	// now all buffers are waiting at eventOne
3705 	// set event eventOne
3706 	VK_CHECK(vk.setEvent(vkDevice, *eventOne));
3707 
3708 	// wait for end of execution of fenceOne
3709 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT));
3710 
3711 	// wait for end of execution of second queue
3712 	VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT));
3713 
3714 	return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded");
3715 }
3716 
3717 /******** 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) **/
orderBindPipelineTest(Context & context)3718 tcu::TestStatus orderBindPipelineTest(Context& context)
3719 {
3720 	const DeviceInterface&					vk						= context.getDeviceInterface();
3721 	const VkDevice							device					= context.getDevice();
3722 	const VkQueue							queue					= context.getUniversalQueue();
3723 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3724 	Allocator&								allocator				= context.getDefaultAllocator();
3725 	const ComputeInstanceResultBuffer		result					(vk, device, allocator);
3726 
3727 	enum
3728 	{
3729 		ADDRESSABLE_SIZE = 256, // allocate a lot more than required
3730 	};
3731 
3732 	const tcu::Vec4							colorA1					= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
3733 	const tcu::Vec4							colorA2					= tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
3734 	const tcu::Vec4							colorB1					= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
3735 	const tcu::Vec4							colorB2					= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
3736 
3737 	const deUint32							dataOffsetA				= (0u);
3738 	const deUint32							dataOffsetB				= (0u);
3739 	const deUint32							viewOffsetA				= (0u);
3740 	const deUint32							viewOffsetB				= (0u);
3741 	const deUint32							bufferSizeA				= dataOffsetA + ADDRESSABLE_SIZE;
3742 	const deUint32							bufferSizeB				= dataOffsetB + ADDRESSABLE_SIZE;
3743 
3744 	de::MovePtr<Allocation>					bufferMemA;
3745 	const Unique<VkBuffer>					bufferA					(createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context));
3746 
3747 	de::MovePtr<Allocation>					bufferMemB;
3748 	const Unique<VkBuffer>					bufferB					(createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB, context));
3749 
3750 	const Unique<VkDescriptorSetLayout>		descriptorSetLayout		(createDescriptorSetLayout(context));
3751 	const Unique<VkDescriptorPool>			descriptorPool			(createDescriptorPool(context));
3752 	const Unique<VkDescriptorSet>			descriptorSet			(createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, result.getBuffer(), context));
3753 	const VkDescriptorSet					descriptorSets[]		= { *descriptorSet };
3754 	const int								numDescriptorSets		= DE_LENGTH_OF_ARRAY(descriptorSets);
3755 
3756 	const VkPipelineLayoutCreateInfo layoutCreateInfo =
3757 	{
3758 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
3759 		DE_NULL,													// pNext
3760 		(VkPipelineLayoutCreateFlags)0,
3761 		numDescriptorSets,											// setLayoutCount
3762 		&descriptorSetLayout.get(),									// pSetLayouts
3763 		0u,															// pushConstantRangeCount
3764 		DE_NULL,													// pPushConstantRanges
3765 	};
3766 	Unique<VkPipelineLayout>				pipelineLayout			(createPipelineLayout(vk, device, &layoutCreateInfo));
3767 
3768 	const Unique<VkShaderModule>			computeModuleGood		(createShaderModule(vk, device, context.getBinaryCollection().get("compute_good"), (VkShaderModuleCreateFlags)0u));
3769 	const Unique<VkShaderModule>			computeModuleBad		(createShaderModule(vk, device, context.getBinaryCollection().get("compute_bad"),  (VkShaderModuleCreateFlags)0u));
3770 
3771 	const VkPipelineShaderStageCreateInfo	shaderCreateInfoGood	=
3772 	{
3773 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3774 		DE_NULL,
3775 		(VkPipelineShaderStageCreateFlags)0,
3776 		VK_SHADER_STAGE_COMPUTE_BIT,								// stage
3777 		*computeModuleGood,											// shader
3778 		"main",
3779 		DE_NULL,													// pSpecializationInfo
3780 	};
3781 
3782 	const VkPipelineShaderStageCreateInfo	shaderCreateInfoBad	=
3783 	{
3784 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3785 		DE_NULL,
3786 		(vk::VkPipelineShaderStageCreateFlags)0,
3787 		vk::VK_SHADER_STAGE_COMPUTE_BIT,							// stage
3788 		*computeModuleBad,											// shader
3789 		"main",
3790 		DE_NULL,													// pSpecializationInfo
3791 	};
3792 
3793 	const VkComputePipelineCreateInfo		createInfoGood			=
3794 	{
3795 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3796 		DE_NULL,
3797 		0u,															// flags
3798 		shaderCreateInfoGood,										// cs
3799 		*pipelineLayout,											// layout
3800 		(vk::VkPipeline)0,											// basePipelineHandle
3801 		0u,															// basePipelineIndex
3802 	};
3803 
3804 	const VkComputePipelineCreateInfo		createInfoBad			=
3805 	{
3806 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3807 		DE_NULL,
3808 		0u,															// flags
3809 		shaderCreateInfoBad,										// cs
3810 		*pipelineLayout,											// descriptorSetLayout.get()
3811 		(VkPipeline)0,												// basePipelineHandle
3812 		0u,															// basePipelineIndex
3813 	};
3814 
3815 	const Unique<VkPipeline>				pipelineGood			(createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoGood));
3816 	const Unique<VkPipeline>				pipelineBad				(createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoBad));
3817 
3818 	const VkAccessFlags						inputBit				= (VK_ACCESS_UNIFORM_READ_BIT);
3819 	const VkBufferMemoryBarrier				bufferBarriers[]		=
3820 	{
3821 		{
3822 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3823 			DE_NULL,
3824 			VK_ACCESS_HOST_WRITE_BIT,									// srcAccessMask
3825 			inputBit,													// dstAccessMask
3826 			VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
3827 			VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
3828 			*bufferA,													// buffer
3829 			(VkDeviceSize)0u,											// offset
3830 			(VkDeviceSize)bufferSizeA,									// size
3831 		},
3832 		{
3833 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3834 			DE_NULL,
3835 			VK_ACCESS_HOST_WRITE_BIT,									// srcAccessMask
3836 			inputBit,													// dstAccessMask
3837 			VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
3838 			VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
3839 			*bufferB,													// buffer
3840 			(VkDeviceSize)0u,											// offset
3841 			(VkDeviceSize)bufferSizeB,									// size
3842 		}
3843 	};
3844 
3845 	const deUint32							numSrcBuffers			= 1u;
3846 
3847 	const deUint32* const					dynamicOffsets			= (DE_NULL);
3848 	const deUint32							numDynamicOffsets		= (0);
3849 	const int								numPreBarriers			= numSrcBuffers;
3850 	const vk::VkBufferMemoryBarrier* const	postBarriers			= result.getResultReadBarrier();
3851 	const int								numPostBarriers			= 1;
3852 	const tcu::Vec4							refQuadrantValue14		= (colorA2);
3853 	const tcu::Vec4							refQuadrantValue23		= (colorA1);
3854 	const tcu::Vec4							references[4]			=
3855 	{
3856 		refQuadrantValue14,
3857 		refQuadrantValue23,
3858 		refQuadrantValue23,
3859 		refQuadrantValue14,
3860 	};
3861 	tcu::Vec4								results[4];
3862 
3863 	// submit and wait begin
3864 
3865 	const tcu::UVec3 numWorkGroups = tcu::UVec3(4, 1u, 1);
3866 
3867 	const VkCommandPoolCreateInfo			cmdPoolCreateInfo		=
3868 	{
3869 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType;
3870 		DE_NULL,													// pNext
3871 		VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,						// flags
3872 		queueFamilyIndex,											// queueFamilyIndex
3873 	};
3874 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, &cmdPoolCreateInfo));
3875 	const VkCommandBufferAllocateInfo		cmdBufCreateInfo		=
3876 	{
3877 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,				// sType
3878 		DE_NULL,													// pNext
3879 		*cmdPool,													// commandPool
3880 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,							// level
3881 		1u,															// bufferCount;
3882 	};
3883 
3884 	const VkCommandBufferBeginInfo			cmdBufBeginInfo			=
3885 	{
3886 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,				// sType
3887 		DE_NULL,													// pNext
3888 		0u,															// flags
3889 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3890 	};
3891 
3892 	const Unique<VkCommandBuffer>			cmd						(allocateCommandBuffer(vk, device, &cmdBufCreateInfo));
3893 
3894 	VK_CHECK(vk.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3895 
3896 	vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineBad);
3897 	vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineGood);
3898 	vk.cmdBindDescriptorSets(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, numDynamicOffsets, dynamicOffsets);
3899 
3900 	if (numPreBarriers)
3901 		vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0,
3902 							  0, (const VkMemoryBarrier*)DE_NULL,
3903 							  numPreBarriers, bufferBarriers,
3904 							  0, (const VkImageMemoryBarrier*)DE_NULL);
3905 
3906 	vk.cmdDispatch(*cmd, numWorkGroups.x(), numWorkGroups.y(), numWorkGroups.z());
3907 	vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
3908 						  0, (const VkMemoryBarrier*)DE_NULL,
3909 						  numPostBarriers, postBarriers,
3910 						  0, (const VkImageMemoryBarrier*)DE_NULL);
3911 	endCommandBuffer(vk, *cmd);
3912 
3913 	// run
3914 	// submit second primary buffer, the secondary should be executed too
3915 	submitCommandsAndWait(vk, device, queue, cmd.get());
3916 
3917 	// submit and wait end
3918 	result.readResultContentsTo(&results);
3919 
3920 	// verify
3921 	if (results[0] == references[0] &&
3922 		results[1] == references[1] &&
3923 		results[2] == references[2] &&
3924 		results[3] == references[3])
3925 	{
3926 		return tcu::TestStatus::pass("Pass");
3927 	}
3928 	else if (results[0] == tcu::Vec4(-1.0f) &&
3929 			 results[1] == tcu::Vec4(-1.0f) &&
3930 			 results[2] == tcu::Vec4(-1.0f) &&
3931 			 results[3] == tcu::Vec4(-1.0f))
3932 	{
3933 		context.getTestContext().getLog()
3934 		<< tcu::TestLog::Message
3935 		<< "Result buffer was not written to."
3936 		<< tcu::TestLog::EndMessage;
3937 		return tcu::TestStatus::fail("Result buffer was not written to");
3938 	}
3939 	else
3940 	{
3941 		context.getTestContext().getLog()
3942 		<< tcu::TestLog::Message
3943 		<< "Error expected ["
3944 		<< references[0] << ", "
3945 		<< references[1] << ", "
3946 		<< references[2] << ", "
3947 		<< references[3] << "], got ["
3948 		<< results[0] << ", "
3949 		<< results[1] << ", "
3950 		<< results[2] << ", "
3951 		<< results[3] << "]"
3952 		<< tcu::TestLog::EndMessage;
3953 		return tcu::TestStatus::fail("Invalid result values");
3954 	}
3955 }
3956 
3957 enum StateTransitionTest
3958 {
3959 	STT_RECORDING_TO_INITIAL	= 0,
3960 	STT_EXECUTABLE_TO_INITIAL,
3961 	STT_RECORDING_TO_INVALID,
3962 	STT_EXECUTABLE_TO_INVALID,
3963 };
3964 
executeStateTransitionTest(Context & context,StateTransitionTest type)3965 tcu::TestStatus executeStateTransitionTest(Context& context, StateTransitionTest type)
3966 {
3967 	const VkDevice					vkDevice			= context.getDevice();
3968 	const DeviceInterface&			vk					= context.getDeviceInterface();
3969 	const VkQueue					queue				= context.getUniversalQueue();
3970 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
3971 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
3972 	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3973 	const Unique<VkEvent>			globalEvent			(createEvent(vk, vkDevice));
3974 
3975 	VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
3976 
3977 	switch (type)
3978 	{
3979 		case STT_RECORDING_TO_INITIAL:
3980 		{
3981 			beginCommandBuffer(vk, *cmdBuffer, 0u);
3982 			vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3983 			break;
3984 			// command buffer is still in recording state
3985 		}
3986 		case STT_EXECUTABLE_TO_INITIAL:
3987 		{
3988 			beginCommandBuffer(vk, *cmdBuffer, 0u);
3989 			vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3990 			endCommandBuffer(vk, *cmdBuffer);
3991 			break;
3992 			// command buffer is still in executable state
3993 		}
3994 		case STT_RECORDING_TO_INVALID:
3995 		{
3996 			VkSubpassDescription subpassDescription;
3997 			deMemset(&subpassDescription, 0, sizeof(VkSubpassDescription));
3998 			subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
3999 
4000 			VkRenderPassCreateInfo renderPassCreateInfo
4001 			{
4002 				VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
4003 				DE_NULL, 0, 0, DE_NULL,
4004 				1, &subpassDescription, 0, DE_NULL
4005 			};
4006 
4007 			// Error here - renderpass and framebuffer were created localy
4008 			Move <VkRenderPass> renderPass = createRenderPass(vk, vkDevice, &renderPassCreateInfo);
4009 
4010 			VkFramebufferCreateInfo framebufferCreateInfo
4011 			{
4012 				VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, DE_NULL,
4013 				0, *renderPass, 0, DE_NULL, 16, 16, 1
4014 			};
4015 			Move <VkFramebuffer> framebuffer = createFramebuffer(vk, vkDevice, &framebufferCreateInfo);
4016 
4017 			VkRenderPassBeginInfo renderPassBeginInfo =
4018 			{
4019 				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4020 				DE_NULL, *renderPass, *framebuffer, { { 0, 0 }, { 16, 16 } },
4021 				0, DE_NULL
4022 			};
4023 
4024 			beginCommandBuffer(vk, *cmdBuffer, 0u);
4025 			vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
4026 			vk.cmdEndRenderPass(*cmdBuffer);
4027 
4028 			// not executing endCommandBuffer(vk, *cmdBuffer);
4029 			// command buffer is still in recording state
4030 			break;
4031 			// renderpass and framebuffer are destroyed; command buffer should be now in invalid state
4032 		}
4033 		case STT_EXECUTABLE_TO_INVALID:
4034 		{
4035 			// create event that will be used to check if command buffer has been executed
4036 			const Unique<VkEvent> localEvent(createEvent(vk, vkDevice));
4037 			VK_CHECK(vk.resetEvent(vkDevice, *localEvent));
4038 
4039 			beginCommandBuffer(vk, *cmdBuffer, 0u);
4040 			vk.cmdSetEvent(*cmdBuffer, *localEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4041 			endCommandBuffer(vk, *cmdBuffer);
4042 			// command buffer is in executable state
4043 			break;
4044 			// localEvent is destroyed; command buffer should be now in invalid state
4045 		}
4046 	}
4047 
4048 	VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
4049 
4050 	vk.resetCommandBuffer(*cmdBuffer, 0u);
4051 	// command buffer should now be back in initial state
4052 
4053 	// verify commandBuffer
4054 	beginCommandBuffer(vk, *cmdBuffer, 0u);
4055 	vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4056 	endCommandBuffer(vk, *cmdBuffer);
4057 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
4058 
4059 	// check if buffer has been executed
4060 	VkResult result = vk.getEventStatus(vkDevice, *globalEvent);
4061 	if (result != VK_EVENT_SET)
4062 		return tcu::TestStatus::fail("Submit failed");
4063 
4064 	return tcu::TestStatus::pass("Pass");
4065 }
4066 
4067 // Shaders
genComputeSource(SourceCollections & programCollection)4068 void genComputeSource (SourceCollections& programCollection)
4069 {
4070 	const char* const						versionDecl				= glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4071 	std::ostringstream						bufGood;
4072 
4073 	bufGood << versionDecl << "\n"
4074 	<< ""
4075 	<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4076 	<< "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4077 	<< "{\n"
4078 	<< "	highp vec4 colorA;\n"
4079 	<< "	highp vec4 colorB;\n"
4080 	<< "} b_instance;\n"
4081 	<< "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4082 	<< "{\n"
4083 	<< "	highp vec4 read_colors[4];\n"
4084 	<< "} b_out;\n"
4085 	<< "void main(void)\n"
4086 	<< "{\n"
4087 	<< "	highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4088 	<< "	highp vec4 result_color;\n"
4089 	<< "	if (quadrant_id == 1 || quadrant_id == 2)\n"
4090 	<< "		result_color = b_instance.colorA;\n"
4091 	<< "	else\n"
4092 	<< "		result_color = b_instance.colorB;\n"
4093 	<< "	b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
4094 	<< "}\n";
4095 
4096 	programCollection.glslSources.add("compute_good") << glu::ComputeSource(bufGood.str());
4097 
4098 	std::ostringstream	bufBad;
4099 
4100 	bufBad	<< versionDecl << "\n"
4101 	<< ""
4102 	<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4103 	<< "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4104 	<< "{\n"
4105 	<< "	highp vec4 colorA;\n"
4106 	<< "	highp vec4 colorB;\n"
4107 	<< "} b_instance;\n"
4108 	<< "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4109 	<< "{\n"
4110 	<< "	highp vec4 read_colors[4];\n"
4111 	<< "} b_out;\n"
4112 	<< "void main(void)\n"
4113 	<< "{\n"
4114 	<< "	highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4115 	<< "	highp vec4 result_color;\n"
4116 	<< "	if (quadrant_id == 1 || quadrant_id == 2)\n"
4117 	<< "		result_color = b_instance.colorA;\n"
4118 	<< "	else\n"
4119 	<< "		result_color = b_instance.colorB;\n"
4120 	<< "	b_out.read_colors[gl_WorkGroupID.x] = vec4(0.0, 0.0, 0.0, 0.0);\n"
4121 	<< "}\n";
4122 
4123 	programCollection.glslSources.add("compute_bad") << glu::ComputeSource(bufBad.str());
4124 }
4125 
genComputeIncrementSource(SourceCollections & programCollection)4126 void genComputeIncrementSource (SourceCollections& programCollection)
4127 {
4128 	const char* const						versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4129 	std::ostringstream						bufIncrement;
4130 
4131 	bufIncrement << versionDecl << "\n"
4132 		<< ""
4133 		<< "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4134 		<< "layout(set = 0, binding = 0, std140) buffer InOutBuf\n"
4135 		<< "{\n"
4136 		<< "    coherent uint count;\n"
4137 		<< "} b_in_out;\n"
4138 		<< "void main(void)\n"
4139 		<< "{\n"
4140 		<< "	atomicAdd(b_in_out.count, 1u);\n"
4141 		<< "}\n";
4142 
4143 	programCollection.glslSources.add("compute_increment") << glu::ComputeSource(bufIncrement.str());
4144 }
4145 
genComputeIncrementSourceBadInheritance(SourceCollections & programCollection,BadInheritanceInfoCase testCase)4146 void genComputeIncrementSourceBadInheritance(SourceCollections& programCollection, BadInheritanceInfoCase testCase)
4147 {
4148 	DE_UNREF(testCase);
4149 	return genComputeIncrementSource(programCollection);
4150 }
4151 
checkEventSupport(Context & context)4152 void checkEventSupport (Context& context)
4153 {
4154 	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getPortabilitySubsetFeatures().events)
4155 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
4156 }
4157 
checkEventSupport(Context & context,const VkCommandBufferLevel)4158 void checkEventSupport (Context& context, const VkCommandBufferLevel)
4159 {
4160 	checkEventSupport(context);
4161 }
4162 
4163 struct ManyDrawsParams
4164 {
4165 	VkCommandBufferLevel	level;
4166 	VkExtent3D				imageExtent;
4167 	deUint32				seed;
4168 
ManyDrawsParamsvkt::api::__anon90601b150111::ManyDrawsParams4169 	ManyDrawsParams(VkCommandBufferLevel level_, const VkExtent3D& extent_, deUint32 seed_)
4170 		: level			(level_)
4171 		, imageExtent	(extent_)
4172 		, seed			(seed_)
4173 	{}
4174 };
4175 
4176 struct ManyDrawsVertex
4177 {
4178 	using Color = tcu::Vector<deUint8, 4>;
4179 
4180 	tcu::Vec2	coords;
4181 	Color		color;
4182 
ManyDrawsVertexvkt::api::__anon90601b150111::ManyDrawsVertex4183 	ManyDrawsVertex (const tcu::Vec2& coords_, const Color& color_) : coords(coords_), color(color_) {}
4184 };
4185 
getSupportedDepthStencilFormat(const InstanceInterface & vki,VkPhysicalDevice physDev)4186 VkFormat getSupportedDepthStencilFormat (const InstanceInterface& vki, VkPhysicalDevice physDev)
4187 {
4188 	const VkFormat				formatList[]	= { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
4189 	const VkFormatFeatureFlags	requirements	= (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
4190 
4191 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(formatList); ++i)
4192 	{
4193 		const auto properties = getPhysicalDeviceFormatProperties(vki, physDev, formatList[i]);
4194 		if ((properties.optimalTilingFeatures & requirements) == requirements)
4195 			return formatList[i];
4196 	}
4197 
4198 	TCU_THROW(NotSupportedError, "No suitable depth/stencil format support");
4199 	return VK_FORMAT_UNDEFINED;
4200 }
4201 
4202 class ManyDrawsCase : public TestCase
4203 {
4204 public:
4205 							ManyDrawsCase			(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params);
~ManyDrawsCase(void)4206 	virtual					~ManyDrawsCase			(void) {}
4207 
4208 	virtual void			checkSupport			(Context& context) const;
4209 	virtual void			initPrograms			(vk::SourceCollections& programCollection) const;
4210 	virtual TestInstance*	createInstance			(Context& context) const;
4211 
getColorFormat(void)4212 	static VkFormat			getColorFormat			(void) { return VK_FORMAT_R8G8B8A8_UINT; }
4213 
4214 protected:
4215 	ManyDrawsParams			m_params;
4216 };
4217 
4218 class ManyDrawsInstance : public TestInstance
4219 {
4220 public:
4221 								ManyDrawsInstance	(Context& context, const ManyDrawsParams& params);
~ManyDrawsInstance(void)4222 	virtual						~ManyDrawsInstance	(void) {}
4223 
4224 	virtual tcu::TestStatus		iterate				(void);
4225 
4226 protected:
4227 	ManyDrawsParams				m_params;
4228 };
4229 
4230 using BufferPtr = de::MovePtr<BufferWithMemory>;
4231 using ImagePtr = de::MovePtr<ImageWithMemory>;
4232 
4233 struct ManyDrawsVertexBuffers
4234 {
4235 	BufferPtr stagingBuffer;
4236 	BufferPtr vertexBuffer;
4237 };
4238 
4239 struct ManyDrawsAllocatedData
4240 {
4241 	ManyDrawsVertexBuffers	frontBuffers;
4242 	ManyDrawsVertexBuffers	backBuffers;
4243 	ImagePtr				colorAttachment;
4244 	ImagePtr				dsAttachment;
4245 	BufferPtr				colorCheckBuffer;
4246 	BufferPtr				stencilCheckBuffer;
4247 
calcNumPixelsvkt::api::__anon90601b150111::ManyDrawsAllocatedData4248 	static deUint32 calcNumPixels (const VkExtent3D& extent)
4249 	{
4250 		DE_ASSERT(extent.depth == 1u);
4251 		return (extent.width * extent.height);
4252 	}
calcNumVerticesvkt::api::__anon90601b150111::ManyDrawsAllocatedData4253 	static deUint32 calcNumVertices (const VkExtent3D& extent)
4254 	{
4255 		// One triangle (3 vertices) per output image pixel.
4256 		return (calcNumPixels(extent) * 3u);
4257 	}
4258 
calcVertexBufferSizevkt::api::__anon90601b150111::ManyDrawsAllocatedData4259 	static VkDeviceSize calcVertexBufferSize (const VkExtent3D& extent)
4260 	{
4261 		return calcNumVertices(extent) * sizeof(ManyDrawsVertex);
4262 	}
4263 
makeVertexBuffersvkt::api::__anon90601b150111::ManyDrawsAllocatedData4264 	static void makeVertexBuffers (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkDeviceSize size, ManyDrawsVertexBuffers& buffers)
4265 	{
4266 		const auto stagingBufferInfo	= makeBufferCreateInfo(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
4267 		const auto vertexBufferInfo		= makeBufferCreateInfo(size, (VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
4268 
4269 		buffers.stagingBuffer	= BufferPtr(new BufferWithMemory(vkd, device, alloc, stagingBufferInfo, MemoryRequirement::HostVisible));
4270 		buffers.vertexBuffer	= BufferPtr(new BufferWithMemory(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::Any));
4271 	}
4272 
ManyDrawsAllocatedDatavkt::api::__anon90601b150111::ManyDrawsAllocatedData4273 	ManyDrawsAllocatedData (const DeviceInterface &vkd, VkDevice device, Allocator &alloc, const VkExtent3D& imageExtent, VkFormat colorFormat, VkFormat dsFormat)
4274 	{
4275 		const auto numPixels		= calcNumPixels(imageExtent);
4276 		const auto vertexBufferSize	= calcVertexBufferSize(imageExtent);
4277 
4278 		makeVertexBuffers(vkd, device, alloc, vertexBufferSize, frontBuffers);
4279 		makeVertexBuffers(vkd, device, alloc, vertexBufferSize, backBuffers);
4280 
4281 		const auto colorUsage	= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4282 		const auto dsUsage		= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4283 
4284 		const VkImageCreateInfo colorAttachmentInfo =
4285 		{
4286 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
4287 			nullptr,								//	const void*				pNext;
4288 			0u,										//	VkImageCreateFlags		flags;
4289 			VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
4290 			colorFormat,							//	VkFormat				format;
4291 			imageExtent,							//	VkExtent3D				extent;
4292 			1u,										//	deUint32				mipLevels;
4293 			1u,										//	deUint32				arrayLayers;
4294 			VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
4295 			VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
4296 			colorUsage,								//	VkImageUsageFlags		usage;
4297 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
4298 			0u,										//	deUint32				queueFamilyIndexCount;
4299 			nullptr,								//	const deUint32*			pQueueFamilyIndices;
4300 			VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
4301 		};
4302 		colorAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, colorAttachmentInfo, MemoryRequirement::Any));
4303 
4304 		const VkImageCreateInfo dsAttachmentInfo =
4305 		{
4306 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
4307 			nullptr,								//	const void*				pNext;
4308 			0u,										//	VkImageCreateFlags		flags;
4309 			VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
4310 			dsFormat,								//	VkFormat				format;
4311 			imageExtent,							//	VkExtent3D				extent;
4312 			1u,										//	deUint32				mipLevels;
4313 			1u,										//	deUint32				arrayLayers;
4314 			VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
4315 			VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
4316 			dsUsage,								//	VkImageUsageFlags		usage;
4317 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
4318 			0u,										//	deUint32				queueFamilyIndexCount;
4319 			nullptr,								//	const deUint32*			pQueueFamilyIndices;
4320 			VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
4321 		};
4322 		dsAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, dsAttachmentInfo, MemoryRequirement::Any));
4323 
4324 		const auto colorCheckBufferSize		= static_cast<VkDeviceSize>(numPixels * tcu::getPixelSize(mapVkFormat(colorFormat)));
4325 		const auto colorCheckBufferInfo		= makeBufferCreateInfo(colorCheckBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
4326 
4327 		colorCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, colorCheckBufferInfo, MemoryRequirement::HostVisible));
4328 
4329 		const auto stencilFormat			= tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
4330 		const auto stencilCheckBufferSize	= static_cast<VkDeviceSize>(numPixels * tcu::getPixelSize(stencilFormat));
4331 		const auto stencilCheckBufferInfo	= makeBufferCreateInfo(stencilCheckBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
4332 
4333 		stencilCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, stencilCheckBufferInfo, MemoryRequirement::HostVisible));
4334 	}
4335 };
4336 
ManyDrawsCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const ManyDrawsParams & params)4337 ManyDrawsCase::ManyDrawsCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params)
4338 	: TestCase	(testCtx, name, description)
4339 	, m_params	(params)
4340 {}
4341 
checkSupport(Context & context) const4342 void ManyDrawsCase::checkSupport (Context& context) const
4343 {
4344 	const auto& vki			= context.getInstanceInterface();
4345 	const auto	physDev		= context.getPhysicalDevice();
4346 	const auto&	vkd			= context.getDeviceInterface();
4347 	const auto	device		= context.getDevice();
4348 	auto&		alloc		= context.getDefaultAllocator();
4349 	const auto	dsFormat	= getSupportedDepthStencilFormat(vki, physDev);
4350 
4351 	try
4352 	{
4353 		ManyDrawsAllocatedData allocatedData(vkd, device, alloc, m_params.imageExtent, getColorFormat(), dsFormat);
4354 	}
4355 	catch (const vk::Error& err)
4356 	{
4357 		const auto result = err.getError();
4358 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_ERROR_OUT_OF_DEVICE_MEMORY)
4359 			TCU_THROW(NotSupportedError, "Not enough memory to run this test");
4360 		throw;
4361 	}
4362 }
4363 
initPrograms(vk::SourceCollections & programCollection) const4364 void ManyDrawsCase::initPrograms (vk::SourceCollections& programCollection) const
4365 {
4366 	std::ostringstream vert;
4367 	vert
4368 		<< "#version 450\n"
4369 		<< "\n"
4370 		<< "layout(location=0) in vec2 inCoords;\n"
4371 		<< "layout(location=1) in uvec4 inColor;\n"
4372 		<< "\n"
4373 		<< "layout(location=0) out flat uvec4 outColor;\n"
4374 		<< "\n"
4375 		<< "void main()\n"
4376 		<< "{\n"
4377 		<< "    gl_Position = vec4(inCoords, 0.0, 1.0);\n"
4378 		<< "    outColor = inColor;\n"
4379 		<< "}\n"
4380 		;
4381 
4382 	std::ostringstream frag;
4383 	frag
4384 		<< "#version 450\n"
4385 		<< "\n"
4386 		<< "layout(location=0) in flat uvec4 inColor;\n"
4387 		<< "layout(location=0) out uvec4 outColor;\n"
4388 		<< "\n"
4389 		<< "void main()\n"
4390 		<< "{\n"
4391 		<< "	outColor = inColor;\n"
4392 		<< "}\n"
4393 		;
4394 
4395 	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
4396 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
4397 }
4398 
createInstance(Context & context) const4399 TestInstance* ManyDrawsCase::createInstance (Context& context) const
4400 {
4401 	return new ManyDrawsInstance(context, m_params);
4402 }
4403 
ManyDrawsInstance(Context & context,const ManyDrawsParams & params)4404 ManyDrawsInstance::ManyDrawsInstance (Context& context, const ManyDrawsParams& params)
4405 	: TestInstance	(context)
4406 	, m_params		(params)
4407 {}
4408 
copyAndFlush(const DeviceInterface & vkd,VkDevice device,BufferWithMemory & buffer,const std::vector<ManyDrawsVertex> & vertices)4409 void copyAndFlush (const DeviceInterface& vkd, VkDevice device, BufferWithMemory& buffer, const std::vector<ManyDrawsVertex>& vertices)
4410 {
4411 	auto& alloc		= buffer.getAllocation();
4412 	void* hostPtr	= alloc.getHostPtr();
4413 
4414 	deMemcpy(hostPtr, vertices.data(), de::dataSize(vertices));
4415 	flushAlloc(vkd, device, alloc);
4416 }
4417 
iterate(void)4418 tcu::TestStatus ManyDrawsInstance::iterate (void)
4419 {
4420 	const auto&	vki					= m_context.getInstanceInterface();
4421 	const auto	physDev				= m_context.getPhysicalDevice();
4422 	const auto&	vkd					= m_context.getDeviceInterface();
4423 	const auto	device				= m_context.getDevice();
4424 	auto&		alloc				= m_context.getDefaultAllocator();
4425 	const auto	qIndex				= m_context.getUniversalQueueFamilyIndex();
4426 	const auto	queue				= m_context.getUniversalQueue();
4427 
4428 	const auto	colorFormat			= ManyDrawsCase::getColorFormat();
4429 	const auto	dsFormat			= getSupportedDepthStencilFormat(vki, physDev);
4430 	const auto	vertexBufferSize	= ManyDrawsAllocatedData::calcVertexBufferSize(m_params.imageExtent);
4431 	const auto	vertexBufferOffset	= static_cast<VkDeviceSize>(0);
4432 	const auto	numPixels			= ManyDrawsAllocatedData::calcNumPixels(m_params.imageExtent);
4433 	const auto	numVertices			= ManyDrawsAllocatedData::calcNumVertices(m_params.imageExtent);
4434 	const auto	alphaValue			= std::numeric_limits<deUint8>::max();
4435 	const auto	pixelWidth			= 2.0f / static_cast<float>(m_params.imageExtent.width);	// Normalized size.
4436 	const auto	pixelWidthHalf		= pixelWidth / 2.0f;										// Normalized size.
4437 	const auto	pixelHeight			= 2.0f / static_cast<float>(m_params.imageExtent.height);	// Normalized size.
4438 	const auto	useSecondary		= (m_params.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4439 
4440 	// Allocate all needed data up front.
4441 	ManyDrawsAllocatedData testData(vkd, device, alloc, m_params.imageExtent, colorFormat, dsFormat);
4442 
4443 	// Generate random colors.
4444 	de::Random							rnd(m_params.seed);
4445 	std::vector<ManyDrawsVertex::Color>	colors;
4446 
4447 	colors.reserve(numPixels);
4448 	for (deUint32 i = 0; i < numPixels; ++i)
4449 	{
4450 #if 0
4451 		const deUint8 red	= ((i      ) & 0xFFu);
4452 		const deUint8 green	= ((i >>  8) & 0xFFu);
4453 		const deUint8 blue	= ((i >> 16) & 0xFFu);
4454 		colors.push_back(ManyDrawsVertex::Color(red, green, blue, alphaValue));
4455 #else
4456 		colors.push_back(ManyDrawsVertex::Color(rnd.getUint8(), rnd.getUint8(), rnd.getUint8(), alphaValue));
4457 #endif
4458 	}
4459 
4460 	// Fill vertex data. One triangle per pixel, front and back.
4461 	std::vector<ManyDrawsVertex> frontVector;
4462 	std::vector<ManyDrawsVertex> backVector;
4463 	frontVector.reserve(numVertices);
4464 	backVector.reserve(numVertices);
4465 
4466 	for (deUint32 y = 0; y < m_params.imageExtent.height; ++y)
4467 	for (deUint32 x = 0; x < m_params.imageExtent.width; ++x)
4468 	{
4469 		float x_left	= static_cast<float>(x) * pixelWidth - 1.0f;
4470 		float x_mid		= x_left + pixelWidthHalf;
4471 		float x_right	= x_left + pixelWidth;
4472 		float y_top		= static_cast<float>(y) * pixelHeight - 1.0f;
4473 		float y_bottom	= y_top + pixelHeight;
4474 
4475 		// Triangles in the "back" mesh will have different colors.
4476 		const auto		colorIdx		= y * m_params.imageExtent.width + x;
4477 		const auto&		frontColor		= colors[colorIdx];
4478 		const auto&		backColor		= colors[colors.size() - 1u - colorIdx];
4479 
4480 		const tcu::Vec2	triangle[3u]	=
4481 		{
4482 			tcu::Vec2(x_left, y_top),
4483 			tcu::Vec2(x_right, y_top),
4484 			tcu::Vec2(x_mid, y_bottom),
4485 		};
4486 
4487 		frontVector.emplace_back(triangle[0], frontColor);
4488 		frontVector.emplace_back(triangle[1], frontColor);
4489 		frontVector.emplace_back(triangle[2], frontColor);
4490 
4491 		backVector.emplace_back(triangle[0], backColor);
4492 		backVector.emplace_back(triangle[1], backColor);
4493 		backVector.emplace_back(triangle[2], backColor);
4494 	}
4495 
4496 	// Copy vertex data to staging buffers.
4497 	copyAndFlush(vkd, device, *testData.frontBuffers.stagingBuffer, frontVector);
4498 	copyAndFlush(vkd, device, *testData.backBuffers.stagingBuffer, backVector);
4499 
4500 	// Color attachment view.
4501 	const auto		colorResourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4502 	const auto		colorAttachmentView	= makeImageView(vkd, device, testData.colorAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorResourceRange);
4503 
4504 	// Depth/stencil attachment view.
4505 	const auto		dsResourceRange		= makeImageSubresourceRange((VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT), 0u, 1u, 0u, 1u);
4506 	const auto		dsAttachmentView	= makeImageView(vkd, device, testData.dsAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsResourceRange);
4507 
4508 	const VkImageView	attachmentArray[]	= { colorAttachmentView.get(), dsAttachmentView.get() };
4509 	const auto			numAttachments		= static_cast<deUint32>(DE_LENGTH_OF_ARRAY(attachmentArray));
4510 
4511 	const auto renderPass	= makeRenderPass(vkd, device, colorFormat, dsFormat);
4512 	const auto framebuffer	= makeFramebuffer(vkd, device, renderPass.get(), numAttachments, attachmentArray, m_params.imageExtent.width, m_params.imageExtent.height);
4513 
4514 	const auto vertModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
4515 	const auto fragModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
4516 
4517 	const std::vector<VkViewport>	viewports	(1u, makeViewport(m_params.imageExtent));
4518 	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(m_params.imageExtent));
4519 
4520 	const auto descriptorSetLayout	= DescriptorSetLayoutBuilder().build(vkd, device);
4521 	const auto pipelineLayout		= makePipelineLayout(vkd, device, descriptorSetLayout.get());
4522 
4523 	const VkVertexInputBindingDescription bindings[] =
4524 	{
4525 		makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(ManyDrawsVertex)), VK_VERTEX_INPUT_RATE_VERTEX),
4526 	};
4527 
4528 	const VkVertexInputAttributeDescription attributes[] =
4529 	{
4530 		makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32_SFLOAT, static_cast<deUint32>(offsetof(ManyDrawsVertex, coords))),
4531 		makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R8G8B8A8_UINT, static_cast<deUint32>(offsetof(ManyDrawsVertex, color))),
4532 	};
4533 
4534 	const VkPipelineVertexInputStateCreateInfo inputState =
4535 	{
4536 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
4537 		nullptr,													//	const void*									pNext;
4538 		0u,															//	VkPipelineVertexInputStateCreateFlags		flags;
4539 		static_cast<deUint32>(DE_LENGTH_OF_ARRAY(bindings)),		//	deUint32									vertexBindingDescriptionCount;
4540 		bindings,													//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
4541 		static_cast<deUint32>(DE_LENGTH_OF_ARRAY(attributes)),		//	deUint32									vertexAttributeDescriptionCount;
4542 		attributes,													//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
4543 	};
4544 
4545 	// Stencil state: this is key for checking and obtaining the right results. The stencil buffer will be cleared to 0. The first
4546 	// set of draws ("front" set of triangles) will pass the test and increment the stencil value to 1. The second set of draws
4547 	// ("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
4548 	// still increment the stencil value to 2.
4549 	//
4550 	// At the end of the test, if every draw command was executed correctly in the expected order, the color buffer will have the
4551 	// colors of the front set, and the stencil buffer will be full of 2s.
4552 	const auto stencilOpState = makeStencilOpState(VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_KEEP,
4553 		VK_COMPARE_OP_EQUAL, 0xFFu, 0xFFu, 0u);
4554 
4555 	const VkPipelineDepthStencilStateCreateInfo dsState =
4556 	{
4557 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType                          sType
4558 		nullptr,													// const void*                              pNext
4559 		0u,															// VkPipelineDepthStencilStateCreateFlags   flags
4560 		VK_FALSE,													// VkBool32                                 depthTestEnable
4561 		VK_FALSE,													// VkBool32                                 depthWriteEnable
4562 		VK_COMPARE_OP_NEVER,										// VkCompareOp                              depthCompareOp
4563 		VK_FALSE,													// VkBool32                                 depthBoundsTestEnable
4564 		VK_TRUE,													// VkBool32                                 stencilTestEnable
4565 		stencilOpState,												// VkStencilOpState                         front
4566 		stencilOpState,												// VkStencilOpState                         back
4567 		0.0f,														// float                                    minDepthBounds
4568 		1.0f,														// float                                    maxDepthBounds
4569 	};
4570 
4571 	const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
4572 			vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(),
4573 			renderPass.get(), viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u,
4574 			&inputState, nullptr, nullptr, &dsState);
4575 
4576 	// Command pool and buffers.
4577 	using CmdBufferPtr = Move<VkCommandBuffer>;
4578 	const auto cmdPool = makeCommandPool(vkd, device, qIndex);
4579 
4580 	CmdBufferPtr	primaryCmdBufferPtr;
4581 	CmdBufferPtr	secondaryCmdBufferPtr;
4582 	VkCommandBuffer	primaryCmdBuffer;
4583 	VkCommandBuffer	secondaryCmdBuffer;
4584 	VkCommandBuffer	drawsCmdBuffer;
4585 
4586 	primaryCmdBufferPtr		= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4587 	primaryCmdBuffer		= primaryCmdBufferPtr.get();
4588 	drawsCmdBuffer			= primaryCmdBuffer;
4589 	beginCommandBuffer(vkd, primaryCmdBuffer);
4590 
4591 	// Clear values.
4592 	std::vector<VkClearValue> clearValues(2u);
4593 	clearValues[0] = makeClearValueColorU32(0u, 0u, 0u, 0u);
4594 	clearValues[1] = makeClearValueDepthStencil(1.0f, 0u);
4595 
4596 	// Copy staging buffers to vertex buffers.
4597 	const auto copyRegion = makeBufferCopy(0ull, 0ull, vertexBufferSize);
4598 	vkd.cmdCopyBuffer(primaryCmdBuffer, testData.frontBuffers.stagingBuffer->get(), testData.frontBuffers.vertexBuffer->get(), 1u, &copyRegion);
4599 	vkd.cmdCopyBuffer(primaryCmdBuffer, testData.backBuffers.stagingBuffer->get(), testData.backBuffers.vertexBuffer->get(), 1u, &copyRegion);
4600 
4601 	// Use barrier for vertex reads.
4602 	const auto vertexBarier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
4603 	vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, 1u, &vertexBarier, 0u, nullptr, 0u, nullptr);
4604 
4605 	// Change depth/stencil attachment layout.
4606 	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);
4607 	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);
4608 
4609 	beginRenderPass(vkd, primaryCmdBuffer, renderPass.get(), framebuffer.get(),
4610 		scissors[0], static_cast<deUint32>(clearValues.size()), clearValues.data(),
4611 		(useSecondary ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE));
4612 
4613 	if (useSecondary)
4614 	{
4615 		secondaryCmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4616 		secondaryCmdBuffer		= secondaryCmdBufferPtr.get();
4617 		drawsCmdBuffer			= secondaryCmdBuffer;
4618 
4619 		const VkCommandBufferInheritanceInfo inheritanceInfo =
4620 		{
4621 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,	//	VkStructureType					sType;
4622 			nullptr,											//	const void*						pNext;
4623 			renderPass.get(),									//	VkRenderPass					renderPass;
4624 			0u,													//	deUint32						subpass;
4625 			framebuffer.get(),									//	VkFramebuffer					framebuffer;
4626 			0u,													//	VkBool32						occlusionQueryEnable;
4627 			0u,													//	VkQueryControlFlags				queryFlags;
4628 			0u,													//	VkQueryPipelineStatisticFlags	pipelineStatistics;
4629 		};
4630 
4631 		const VkCommandBufferUsageFlags	usageFlags	= (VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
4632 		const VkCommandBufferBeginInfo	beginInfo	=
4633 		{
4634 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4635 			nullptr,
4636 			usageFlags,										//	VkCommandBufferUsageFlags				flags;
4637 			&inheritanceInfo,								//	const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
4638 		};
4639 
4640 		VK_CHECK(vkd.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
4641 	}
4642 
4643 	// Bind pipeline.
4644 	vkd.cmdBindPipeline(drawsCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
4645 
4646 	// Draw triangles in front.
4647 	vkd.cmdBindVertexBuffers(drawsCmdBuffer, 0u, 1u, &testData.frontBuffers.vertexBuffer->get(), &vertexBufferOffset);
4648 	for (deUint32 i = 0; i < numPixels; ++i)
4649 		vkd.cmdDraw(drawsCmdBuffer, 3u, 1u, i*3u, 0u);
4650 
4651 	// Draw triangles in the "back". This should have no effect due to the stencil test.
4652 	vkd.cmdBindVertexBuffers(drawsCmdBuffer, 0u, 1u, &testData.backBuffers.vertexBuffer->get(), &vertexBufferOffset);
4653 	for (deUint32 i = 0; i < numPixels; ++i)
4654 		vkd.cmdDraw(drawsCmdBuffer, 3u, 1u, i*3u, 0u);
4655 
4656 	if (useSecondary)
4657 	{
4658 		endCommandBuffer(vkd, secondaryCmdBuffer);
4659 		vkd.cmdExecuteCommands(primaryCmdBuffer, 1u, &secondaryCmdBuffer);
4660 	}
4661 
4662 	endRenderPass(vkd, primaryCmdBuffer);
4663 
4664 	// Copy color and depth/stencil attachments to verification buffers.
4665 	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);
4666 	vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorAttachmentBarrier);
4667 
4668 	const auto colorResourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
4669 	const auto colorCopyRegion		= makeBufferImageCopy(m_params.imageExtent, colorResourceLayers);
4670 	vkd.cmdCopyImageToBuffer(primaryCmdBuffer, testData.colorAttachment->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.colorCheckBuffer->get(), 1u, &colorCopyRegion);
4671 
4672 	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);
4673 	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);
4674 
4675 	const auto stencilResourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u);
4676 	const auto stencilCopyRegion		= makeBufferImageCopy(m_params.imageExtent, stencilResourceLayers);
4677 	vkd.cmdCopyImageToBuffer(primaryCmdBuffer, testData.dsAttachment->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.stencilCheckBuffer->get(), 1u, &stencilCopyRegion);
4678 
4679 	const auto verificationBuffersBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
4680 	vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &verificationBuffersBarrier, 0u, nullptr, 0u, nullptr);
4681 
4682 	endCommandBuffer(vkd, primaryCmdBuffer);
4683 	submitCommandsAndWait(vkd, device, queue, primaryCmdBuffer);
4684 
4685 	// Check buffer contents.
4686 	auto& colorCheckBufferAlloc	= testData.colorCheckBuffer->getAllocation();
4687 	void* colorCheckBufferData	= colorCheckBufferAlloc.getHostPtr();
4688 	invalidateAlloc(vkd, device, colorCheckBufferAlloc);
4689 
4690 	auto& stencilCheckBufferAlloc	= testData.stencilCheckBuffer->getAllocation();
4691 	void* stencilCheckBufferData	= stencilCheckBufferAlloc.getHostPtr();
4692 	invalidateAlloc(vkd, device, stencilCheckBufferAlloc);
4693 
4694 	const auto iWidth			= static_cast<int>(m_params.imageExtent.width);
4695 	const auto iHeight			= static_cast<int>(m_params.imageExtent.height);
4696 	const auto colorTcuFormat	= mapVkFormat(colorFormat);
4697 	const auto stencilTcuFormat	= tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
4698 
4699 	tcu::TextureLevel			referenceLevel		(colorTcuFormat, iWidth, iHeight);
4700 	tcu::PixelBufferAccess		referenceAccess		= referenceLevel.getAccess();
4701 	tcu::TextureLevel			colorErrorLevel		(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), iWidth, iHeight);
4702 	tcu::PixelBufferAccess		colorErrorAccess	= colorErrorLevel.getAccess();
4703 	tcu::TextureLevel			stencilErrorLevel	(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), iWidth, iHeight);
4704 	tcu::PixelBufferAccess		stencilErrorAccess	= stencilErrorLevel.getAccess();
4705 	tcu::ConstPixelBufferAccess	colorAccess			(colorTcuFormat, iWidth, iHeight, 1, colorCheckBufferData);
4706 	tcu::ConstPixelBufferAccess	stencilAccess		(stencilTcuFormat, iWidth, iHeight, 1, stencilCheckBufferData);
4707 	const tcu::Vec4				green				(0.0f, 1.0f, 0.0f, 1.0f);
4708 	const tcu::Vec4				red					(1.0f, 0.0f, 0.0f, 1.0f);
4709 	const int					expectedStencil		= 2;
4710 	bool						colorFail			= false;
4711 	bool						stencilFail			= false;
4712 
4713 	for (int y = 0; y < iHeight; ++y)
4714 	for (int x = 0; x < iWidth; ++x)
4715 	{
4716 		const tcu::UVec4	colorValue		= colorAccess.getPixelUint(x, y);
4717 		const auto			expectedPixel	= colors[y * iWidth + x];
4718 		const tcu::UVec4	expectedValue	(expectedPixel.x(), expectedPixel.y(), expectedPixel.z(), expectedPixel.w());
4719 		const bool			colorMismatch	= (colorValue != expectedValue);
4720 
4721 		const auto			stencilValue	= stencilAccess.getPixStencil(x, y);
4722 		const bool			stencilMismatch	= (stencilValue != expectedStencil);
4723 
4724 		referenceAccess.setPixel(expectedValue, x, y);
4725 		colorErrorAccess.setPixel((colorMismatch ? red : green), x, y);
4726 		stencilErrorAccess.setPixel((stencilMismatch ? red : green), x, y);
4727 
4728 		if (stencilMismatch)
4729 			stencilFail = true;
4730 
4731 		if (colorMismatch)
4732 			colorFail = true;
4733 	}
4734 
4735 	if (colorFail || stencilFail)
4736 	{
4737 		auto& log = m_context.getTestContext().getLog();
4738 		log
4739 			<< tcu::TestLog::ImageSet("Result", "")
4740 			<< tcu::TestLog::Image("ColorOutput", "", colorAccess)
4741 			<< tcu::TestLog::Image("ColorReference", "", referenceAccess)
4742 			<< tcu::TestLog::Image("ColorError", "", colorErrorAccess)
4743 			<< tcu::TestLog::Image("StencilError", "", stencilErrorAccess)
4744 			<< tcu::TestLog::EndImageSet
4745 			;
4746 		TCU_FAIL("Mismatched output and reference color or stencil; please check test log --");
4747 	}
4748 
4749 	return tcu::TestStatus::pass("Pass");
4750 }
4751 
4752 } // anonymous
4753 
createCommandBuffersTests(tcu::TestContext & testCtx)4754 tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx)
4755 {
4756 	de::MovePtr<tcu::TestCaseGroup>	commandBuffersTests	(new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests"));
4757 
4758 	/* 19.1. Command Pools (5.1 in VK 1.0 Spec) */
4759 	addFunctionCase				(commandBuffersTests.get(), "pool_create_null_params",			"",	createPoolNullParamsTest);
4760 	addFunctionCase				(commandBuffersTests.get(), "pool_create_non_null_allocator",	"",	createPoolNonNullAllocatorTest);
4761 	addFunctionCase				(commandBuffersTests.get(), "pool_create_transient_bit",		"",	createPoolTransientBitTest);
4762 	addFunctionCase				(commandBuffersTests.get(), "pool_create_reset_bit",			"",	createPoolResetBitTest);
4763 	addFunctionCase				(commandBuffersTests.get(), "pool_reset_release_res",			"",	resetPoolReleaseResourcesBitTest);
4764 	addFunctionCase				(commandBuffersTests.get(), "pool_reset_no_flags_res",			"",	resetPoolNoFlagsTest);
4765 	addFunctionCase				(commandBuffersTests.get(), "pool_reset_reuse",					"",	checkEventSupport, resetPoolReuseTest);
4766 	/* 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) */
4767 	addFunctionCase				(commandBuffersTests.get(), "allocate_single_primary",			"", allocatePrimaryBufferTest);
4768 	addFunctionCase				(commandBuffersTests.get(), "allocate_many_primary",			"",	allocateManyPrimaryBuffersTest);
4769 	addFunctionCase				(commandBuffersTests.get(), "allocate_single_secondary",		"", allocateSecondaryBufferTest);
4770 	addFunctionCase				(commandBuffersTests.get(), "allocate_many_secondary",			"", allocateManySecondaryBuffersTest);
4771 	addFunctionCase				(commandBuffersTests.get(), "execute_small_primary",			"",	checkEventSupport, executePrimaryBufferTest);
4772 	addFunctionCase				(commandBuffersTests.get(), "execute_large_primary",			"",	checkEventSupport, executeLargePrimaryBufferTest);
4773 	addFunctionCase				(commandBuffersTests.get(), "reset_implicit",					"", checkEventSupport, resetBufferImplicitlyTest);
4774 	addFunctionCase				(commandBuffersTests.get(), "trim_command_pool",				"", checkEventSupport, trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4775 	addFunctionCase				(commandBuffersTests.get(), "trim_command_pool_secondary",		"", checkEventSupport, trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4776 	/* 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) */
4777 	addFunctionCase				(commandBuffersTests.get(), "record_single_primary",			"",	checkEventSupport, recordSinglePrimaryBufferTest);
4778 	addFunctionCase				(commandBuffersTests.get(), "record_many_primary",				"", checkEventSupport, recordLargePrimaryBufferTest);
4779 	addFunctionCase				(commandBuffersTests.get(), "record_single_secondary",			"",	checkEventSupport, recordSingleSecondaryBufferTest);
4780 	addFunctionCase				(commandBuffersTests.get(), "record_many_secondary",			"", checkEventSupport, recordLargeSecondaryBufferTest);
4781 	{
4782 		deUint32	seed		= 1614182419u;
4783 		const auto	smallExtent	= makeExtent3D(128u, 128u, 1u);
4784 		const auto	largeExtent	= makeExtent3D(512u, 512u, 1u);
4785 
4786 		commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_primary_1",		"", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_PRIMARY,	smallExtent,	seed++)));
4787 		commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_primary_2",		"", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_PRIMARY,	largeExtent,	seed++)));
4788 		commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_secondary_1",	"", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_SECONDARY,	smallExtent,	seed++)));
4789 		commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_secondary_2",	"", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_SECONDARY,	largeExtent,	seed++)));
4790 	}
4791 	addFunctionCase				(commandBuffersTests.get(), "submit_twice_primary",				"",	checkEventSupport, submitPrimaryBufferTwiceTest);
4792 	addFunctionCase				(commandBuffersTests.get(), "submit_twice_secondary",			"",	checkEventSupport, submitSecondaryBufferTwiceTest);
4793 	addFunctionCase				(commandBuffersTests.get(), "record_one_time_submit_primary",	"",	checkEventSupport, oneTimeSubmitFlagPrimaryBufferTest);
4794 	addFunctionCase				(commandBuffersTests.get(), "record_one_time_submit_secondary",	"",	checkEventSupport, oneTimeSubmitFlagSecondaryBufferTest);
4795 	addFunctionCase				(commandBuffersTests.get(), "render_pass_continue",				"",	renderPassContinueTest, true);
4796 	addFunctionCase				(commandBuffersTests.get(), "render_pass_continue_no_fb",		"",	renderPassContinueTest, false);
4797 	addFunctionCase				(commandBuffersTests.get(), "record_simul_use_primary",			"",	checkEventSupport, simultaneousUsePrimaryBufferTest);
4798 	addFunctionCase				(commandBuffersTests.get(), "record_simul_use_secondary",		"",	checkEventSupport, simultaneousUseSecondaryBufferTest);
4799 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_one_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferOnePrimaryBufferTest);
4800 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_two_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferTwoPrimaryBuffersTest);
4801 	addFunctionCase				(commandBuffersTests.get(), "record_query_precise_w_flag",		"",	recordBufferQueryPreciseWithFlagTest);
4802 	addFunctionCase				(commandBuffersTests.get(), "record_query_imprecise_w_flag",	"",	recordBufferQueryImpreciseWithFlagTest);
4803 	addFunctionCase				(commandBuffersTests.get(), "record_query_imprecise_wo_flag",	"",	recordBufferQueryImpreciseWithoutFlagTest);
4804 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random",		"", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_PTR);
4805 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random_cont",	"", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION);
4806 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random_data",	"", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_DATA_PTR);
4807 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_invalid_type", "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::INVALID_STRUCTURE_TYPE);
4808 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_valid_nonsense_type", "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::VALID_NONSENSE_TYPE);
4809 	/* 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) */
4810 	addFunctionCase				(commandBuffersTests.get(), "submit_count_non_zero",			"", checkEventSupport, submitBufferCountNonZero);
4811 	addFunctionCase				(commandBuffersTests.get(), "submit_count_equal_zero",			"", checkEventSupport, submitBufferCountEqualZero);
4812 	addFunctionCase				(commandBuffersTests.get(), "submit_wait_single_semaphore",		"", checkEventSupport, submitBufferWaitSingleSemaphore);
4813 	addFunctionCase				(commandBuffersTests.get(), "submit_wait_many_semaphores",		"", checkEventSupport, submitBufferWaitManySemaphores);
4814 	addFunctionCase				(commandBuffersTests.get(), "submit_null_fence",				"", checkEventSupport, submitBufferNullFence);
4815 	addFunctionCase				(commandBuffersTests.get(), "submit_two_buffers_one_buffer_null_with_fence", "", checkEventSupport, submitTwoBuffersOneBufferNullWithFence);
4816 	/* 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) */
4817 	addFunctionCase				(commandBuffersTests.get(), "secondary_execute",				"",	checkEventSupport, executeSecondaryBufferTest);
4818 	addFunctionCase				(commandBuffersTests.get(), "secondary_execute_twice",			"",	checkEventSupport, executeSecondaryBufferTwiceTest);
4819 	/* 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) */
4820 	addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_bind_pipeline",				"", genComputeSource, orderBindPipelineTest);
4821 	/* Verify untested transitions between command buffer states */
4822 	addFunctionCase				(commandBuffersTests.get(), "recording_to_ininitial",			"", executeStateTransitionTest, STT_RECORDING_TO_INITIAL);
4823 	addFunctionCase				(commandBuffersTests.get(), "executable_to_ininitial",			"", executeStateTransitionTest, STT_EXECUTABLE_TO_INITIAL);
4824 	addFunctionCase				(commandBuffersTests.get(), "recording_to_invalid",				"", executeStateTransitionTest, STT_RECORDING_TO_INVALID);
4825 	addFunctionCase				(commandBuffersTests.get(), "executable_to_invalid",			"", executeStateTransitionTest, STT_EXECUTABLE_TO_INVALID);
4826 
4827 	return commandBuffersTests.release();
4828 }
4829 
4830 } // api
4831 } // vkt
4832 
4833