• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Platform Synchronization tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationSmokeTests.hpp"
25 #include "vktSynchronizationUtil.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktCustomInstancesDevices.hpp"
29 
30 #include "vkPlatform.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkDeviceUtil.hpp"
35 #include "vkSafetyCriticalUtil.hpp"
36 
37 #include "tcuTestLog.hpp"
38 #include "tcuFormatUtil.hpp"
39 #include "tcuCommandLine.hpp"
40 
41 #include "deUniquePtr.hpp"
42 #include "deThread.hpp"
43 #include "vkMemUtil.hpp"
44 #include "vkQueryUtil.hpp"
45 #include "vkPrograms.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 
49 #include <limits>
50 
51 namespace vkt
52 {
53 namespace synchronization
54 {
55 
56 using namespace vk;
57 using namespace tcu;
58 
59 namespace
60 {
61 
62 using std::vector;
63 using std::string;
64 using tcu::TestLog;
65 using de::MovePtr;
66 
67 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
68 
69 struct SemaphoreTestConfig
70 {
71 	SynchronizationType		synchronizationType;
72 	VkSemaphoreType			semaphoreType;
73 };
74 
initShaders(SourceCollections & shaderCollection,SemaphoreTestConfig)75 void initShaders(SourceCollections& shaderCollection, SemaphoreTestConfig)
76 {
77 	shaderCollection.glslSources.add("glslvert") <<
78 		glu::VertexSource(
79 				"#version 310 es\n"
80 				"precision mediump float;\n"
81 				"layout (location = 0) in vec4 vertexPosition;\n"
82 				"void main()\n"
83 				"{\n"
84 				"	gl_Position = vertexPosition;\n"
85 				"}\n");
86 
87 	shaderCollection.glslSources.add("glslfrag") <<
88 		glu::FragmentSource(
89 				"#version 310 es\n"
90 				"precision mediump float;\n"
91 				"layout (location = 0) out vec4 outputColor;\n"
92 				"void main()\n"
93 				"{\n"
94 				"	outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
95 				"}\n");
96 }
97 
buildShaders(SourceCollections & shaderCollection)98 void buildShaders(SourceCollections& shaderCollection)
99 {
100 	initShaders(shaderCollection, { SynchronizationType::LEGACY, VK_SEMAPHORE_TYPE_BINARY });
101 }
102 
createTestDevice(Context & context,SemaphoreTestConfig & config,const VkInstance & instance,const InstanceInterface & vki,deUint32 * outQueueFamilyIndex)103 Move<VkDevice> createTestDevice (Context& context, SemaphoreTestConfig& config, const VkInstance& instance, const InstanceInterface& vki, deUint32* outQueueFamilyIndex)
104 {
105 	const PlatformInterface&	vkp							= context.getPlatformInterface();
106 	VkPhysicalDevice			physicalDevice				= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
107 	bool						validationEnabled			= context.getTestContext().getCommandLine().isValidationEnabled();
108 	VkDeviceQueueCreateInfo		queueInfo;
109 	VkDeviceCreateInfo			deviceInfo;
110 	size_t						queueNdx;
111 	const deUint32				queueCount					= 2u;
112 	const float					queuePriority[queueCount]	= { 1.0f, 1.0f };
113 
114 	const vector<VkQueueFamilyProperties>			queueProps					= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
115 	const VkPhysicalDeviceFeatures					physicalDeviceFeatures		= getPhysicalDeviceFeatures(vki, physicalDevice);
116 	VkPhysicalDeviceFeatures2						physicalDeviceFeatures2		{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, physicalDeviceFeatures };
117 	VkPhysicalDeviceSynchronization2FeaturesKHR		synchronization2Features	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, DE_NULL, DE_TRUE };
118 	VkPhysicalDeviceTimelineSemaphoreFeatures		timelineSemaphoreFeatures	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, DE_NULL, DE_TRUE };
119 	void**											nextPtr						= &physicalDeviceFeatures2.pNext;
120 
121 	for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
122 	{
123 		if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount))
124 			break;
125 	}
126 
127 	if (queueNdx >= queueProps.size())
128 	{
129 		// No queue family index found
130 		std::ostringstream msg;
131 		msg << "Cannot create device with " << queueCount << " graphics queues";
132 
133 		throw tcu::NotSupportedError(msg.str());
134 	}
135 
136 	deMemset(&queueInfo,	0, sizeof(queueInfo));
137 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
138 
139 	deMemset(&queueInfo, 0xcd, sizeof(queueInfo));
140 	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
141 	queueInfo.pNext							= DE_NULL;
142 	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
143 	queueInfo.queueFamilyIndex				= (deUint32)queueNdx;
144 	queueInfo.queueCount					= queueCount;
145 	queueInfo.pQueuePriorities				= queuePriority;
146 
147 	vector<const char*> deviceExtensions;
148 	bool useFeatures2 = false;
149 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
150 	{
151 		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_timeline_semaphore"))
152 			deviceExtensions.push_back("VK_KHR_timeline_semaphore");
153 		addToChainVulkanStructure(&nextPtr, timelineSemaphoreFeatures);
154 		useFeatures2 = true;
155 	}
156 	if (config.synchronizationType == SynchronizationType::SYNCHRONIZATION2)
157 	{
158 		deviceExtensions.push_back("VK_KHR_synchronization2");
159 		addToChainVulkanStructure(&nextPtr, synchronization2Features);
160 		useFeatures2 = true;
161 	}
162 
163 	void* pNext												= !useFeatures2 ? DE_NULL : &physicalDeviceFeatures2;
164 #ifdef CTS_USES_VULKANSC
165 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
166 	memReservationInfo.pNext								= pNext;
167 	pNext													= &memReservationInfo;
168 
169 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
170 	sc10Features.pNext										= pNext;
171 	pNext													= &sc10Features;
172 
173 	VkPipelineCacheCreateInfo			pcCI;
174 	std::vector<VkPipelinePoolSize>		poolSizes;
175 	if (context.getTestContext().getCommandLine().isSubProcess())
176 	{
177 		if (context.getResourceInterface()->getCacheDataSize() > 0)
178 		{
179 			pcCI =
180 			{
181 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
182 				DE_NULL,											// const void*					pNext;
183 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
184 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
185 				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
186 				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
187 			};
188 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
189 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
190 		}
191 
192 		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
193 		if (!poolSizes.empty())
194 		{
195 			memReservationInfo.pipelinePoolSizeCount			= deUint32(poolSizes.size());
196 			memReservationInfo.pPipelinePoolSizes				= poolSizes.data();
197 		}
198 	}
199 #endif // CTS_USES_VULKANSC
200 
201 	deMemset(&deviceInfo, 0xcd, sizeof(deviceInfo));
202 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
203 	deviceInfo.pNext						= pNext;
204 	deviceInfo.flags						= (VkDeviceCreateFlags)0u;
205 	deviceInfo.queueCreateInfoCount			= 1u;
206 	deviceInfo.pQueueCreateInfos			= &queueInfo;
207 	deviceInfo.enabledExtensionCount		= static_cast<deUint32>(deviceExtensions.size());
208 	deviceInfo.ppEnabledExtensionNames		= deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0];
209 	deviceInfo.enabledLayerCount			= 0u;
210 	deviceInfo.ppEnabledLayerNames			= DE_NULL;
211 	deviceInfo.pEnabledFeatures				= !useFeatures2 ? &physicalDeviceFeatures : DE_NULL;
212 
213 	*outQueueFamilyIndex					= queueInfo.queueFamilyIndex;
214 
215 	return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceInfo);
216 }
217 
218 struct BufferParameters
219 {
220 	const void*						memory;
221 	VkDeviceSize					size;
222 	VkBufferUsageFlags				usage;
223 	VkSharingMode					sharingMode;
224 	deUint32						queueFamilyCount;
225 	const deUint32*					queueFamilyIndex;
226 	VkAccessFlags					inputBarrierFlags;
227 };
228 
229 struct Buffer
230 {
231 	MovePtr<Allocation>				allocation;
232 	vector<VkMemoryBarrier>			memoryBarrier;
233 	vk::Move<VkBuffer>				buffer;
234 };
235 
createVulkanBuffer(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const BufferParameters & bufferParameters,Buffer & buffer,MemoryRequirement visibility)236 void createVulkanBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
237 {
238 	VkBufferCreateInfo	bufferCreateParams;
239 
240 	deMemset(&bufferCreateParams, 0xcd, sizeof(bufferCreateParams));
241 	bufferCreateParams.sType					= VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
242 	bufferCreateParams.pNext					= DE_NULL;
243 	bufferCreateParams.flags					= 0;
244 	bufferCreateParams.size						= bufferParameters.size;
245 	bufferCreateParams.usage					= bufferParameters.usage;
246 	bufferCreateParams.sharingMode				= bufferParameters.sharingMode;
247 	bufferCreateParams.queueFamilyIndexCount	= bufferParameters.queueFamilyCount;
248 	bufferCreateParams.pQueueFamilyIndices		= bufferParameters.queueFamilyIndex;
249 
250 	buffer.buffer		= createBuffer(vkd, device, &bufferCreateParams);
251 	buffer.allocation	= allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer.buffer), visibility);
252 
253 	VK_CHECK(vkd.bindBufferMemory(device, *buffer.buffer, buffer.allocation->getMemory(), buffer.allocation->getOffset()));
254 
255 	// If caller provides a host memory buffer for the allocation, then go
256 	// ahead and copy the provided data into the allocation and update the
257 	// barrier list with the associated access
258 	if (bufferParameters.memory != DE_NULL)
259 	{
260 		VkMemoryBarrier				barrier;
261 
262 		deMemcpy(buffer.allocation->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
263 		flushAlloc(vkd, device, *buffer.allocation);
264 
265 		deMemset(&barrier, 0xcd, sizeof(barrier));
266 		barrier.sType			= VK_STRUCTURE_TYPE_MEMORY_BARRIER;
267 		barrier.pNext			= DE_NULL;
268 		barrier.srcAccessMask	= VK_ACCESS_HOST_WRITE_BIT;
269 		barrier.dstAccessMask	= bufferParameters.inputBarrierFlags;
270 
271 		buffer.memoryBarrier.push_back(barrier);
272 	}
273 }
274 
275 struct ImageParameters
276 {
277 	VkImageType							imageType;
278 	VkFormat							format;
279 	VkExtent3D							extent3D;
280 	deUint32							mipLevels;
281 	VkSampleCountFlagBits				samples;
282 	VkImageTiling						tiling;
283 	VkBufferUsageFlags					usage;
284 	VkSharingMode						sharingMode;
285 	deUint32							queueFamilyCount;
286 	const deUint32*						queueFamilyNdxList;
287 	VkImageLayout						initialLayout;
288 	VkImageLayout						finalLayout;
289 	VkAccessFlags						barrierInputMask;
290 };
291 
292 struct Image
293 {
294 	vk::Move<VkImage>					image;
295 	vk::Move<VkImageView>				imageView;
296 	MovePtr<Allocation>					allocation;
297 	vector<VkImageMemoryBarrier>		imageMemoryBarrier;
298 };
299 
createVulkanImage(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const ImageParameters & imageParameters,Image & image,MemoryRequirement visibility)300 void createVulkanImage (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
301 {
302 	VkComponentMapping			componentMap;
303 	VkImageSubresourceRange		subresourceRange;
304 	VkImageViewCreateInfo		imageViewCreateInfo;
305 	VkImageCreateInfo			imageCreateParams;
306 	VkImageMemoryBarrier		imageBarrier;
307 
308 	deMemset(&imageCreateParams, 0xcd, sizeof(imageCreateParams));
309 	imageCreateParams.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
310 	imageCreateParams.pNext					= DE_NULL;
311 	imageCreateParams.flags					= 0;
312 	imageCreateParams.imageType				= imageParameters.imageType;
313 	imageCreateParams.format				= imageParameters.format;
314 	imageCreateParams.extent				= imageParameters.extent3D;
315 	imageCreateParams.mipLevels				= imageParameters.mipLevels;
316 	imageCreateParams.arrayLayers			= 1;
317 	imageCreateParams.samples				= imageParameters.samples;
318 	imageCreateParams.tiling				= imageParameters.tiling;
319 	imageCreateParams.usage					= imageParameters.usage;
320 	imageCreateParams.sharingMode			= imageParameters.sharingMode;
321 	imageCreateParams.queueFamilyIndexCount	= imageParameters.queueFamilyCount;
322 	imageCreateParams.pQueueFamilyIndices	= imageParameters.queueFamilyNdxList;
323 	imageCreateParams.initialLayout			= imageParameters.initialLayout;
324 
325 	image.image			= createImage(vkd, device, &imageCreateParams);
326 	image.allocation	= allocator.allocate(getImageMemoryRequirements(vkd, device, *image.image), visibility);
327 
328 	VK_CHECK(vkd.bindImageMemory(device, *image.image, image.allocation->getMemory(), image.allocation->getOffset()));
329 
330 	componentMap.r							= VK_COMPONENT_SWIZZLE_R;
331 	componentMap.g							= VK_COMPONENT_SWIZZLE_G;
332 	componentMap.b							= VK_COMPONENT_SWIZZLE_B;
333 	componentMap.a							= VK_COMPONENT_SWIZZLE_A;
334 
335 	subresourceRange.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
336 	subresourceRange.baseMipLevel			= 0;
337 	subresourceRange.levelCount				= imageParameters.mipLevels;
338 	subresourceRange.baseArrayLayer			= 0;
339 	subresourceRange.layerCount				= 1;
340 
341 	deMemset(&imageViewCreateInfo, 0xcd, sizeof(imageViewCreateInfo));
342 	imageViewCreateInfo.sType				= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
343 	imageViewCreateInfo.pNext				= DE_NULL;
344 	imageViewCreateInfo.flags				= 0;
345 	imageViewCreateInfo.image				= image.image.get();
346 	imageViewCreateInfo.viewType			= VK_IMAGE_VIEW_TYPE_2D;
347 	imageViewCreateInfo.format				= imageParameters.format;
348 	imageViewCreateInfo.components			= componentMap;
349 	imageViewCreateInfo.subresourceRange	= subresourceRange;
350 
351 	image.imageView	= createImageView(vkd, device, &imageViewCreateInfo);
352 
353 	deMemset(&imageBarrier, 0xcd, sizeof(imageBarrier));
354 	imageBarrier.sType					= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
355 	imageBarrier.pNext					= DE_NULL;
356 	imageBarrier.srcAccessMask			= 0;
357 	imageBarrier.dstAccessMask			= imageParameters.barrierInputMask;
358 	imageBarrier.oldLayout				= imageParameters.initialLayout;
359 	imageBarrier.newLayout				= imageParameters.finalLayout;
360 	imageBarrier.srcQueueFamilyIndex	= imageParameters.queueFamilyNdxList[0];
361 	imageBarrier.dstQueueFamilyIndex	= imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
362 	imageBarrier.image					= image.image.get();
363 	imageBarrier.subresourceRange		= subresourceRange;
364 
365 	image.imageMemoryBarrier.push_back(imageBarrier);
366 }
367 
368 struct RenderPassParameters
369 {
370 	VkFormat				colorFormat;
371 	VkSampleCountFlagBits	colorSamples;
372 };
373 
createColorOnlyRenderPass(const DeviceInterface & vkd,VkDevice device,const RenderPassParameters & renderPassParameters,vk::Move<VkRenderPass> & renderPass)374 void  createColorOnlyRenderPass (const DeviceInterface& vkd, VkDevice device, const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
375 {
376 	VkAttachmentDescription				colorAttachmentDesc;
377 	VkAttachmentReference				colorAttachmentRef;
378 	VkAttachmentReference				stencilAttachmentRef;
379 	VkSubpassDescription				subpassDesc;
380 	VkRenderPassCreateInfo				renderPassParams;
381 	VkRenderPass						newRenderPass;
382 
383 	colorAttachmentDesc.flags			= 0;
384 	colorAttachmentDesc.format			= renderPassParameters.colorFormat;
385 	colorAttachmentDesc.samples			= renderPassParameters.colorSamples;
386 	colorAttachmentDesc.loadOp			= VK_ATTACHMENT_LOAD_OP_CLEAR;
387 	colorAttachmentDesc.storeOp			= VK_ATTACHMENT_STORE_OP_STORE;
388 	colorAttachmentDesc.stencilLoadOp	= VK_ATTACHMENT_LOAD_OP_DONT_CARE;
389 	colorAttachmentDesc.stencilStoreOp	= VK_ATTACHMENT_STORE_OP_DONT_CARE;
390 	colorAttachmentDesc.initialLayout	= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
391 	colorAttachmentDesc.finalLayout		= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
392 
393 	colorAttachmentRef.attachment		= 0;
394 	colorAttachmentRef.layout			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
395 
396 	stencilAttachmentRef.attachment		= VK_ATTACHMENT_UNUSED;
397 	stencilAttachmentRef.layout			= VK_IMAGE_LAYOUT_UNDEFINED;
398 
399 	subpassDesc.flags					= 0;
400 	subpassDesc.pipelineBindPoint		= VK_PIPELINE_BIND_POINT_GRAPHICS;
401 	subpassDesc.inputAttachmentCount	= 0;
402 	subpassDesc.pInputAttachments		= DE_NULL;
403 	subpassDesc.colorAttachmentCount	= 1;
404 	subpassDesc.pColorAttachments		= &colorAttachmentRef;
405 	subpassDesc.pResolveAttachments		= DE_NULL;
406 	subpassDesc.pDepthStencilAttachment	= &stencilAttachmentRef;
407 	subpassDesc.preserveAttachmentCount	= 0;
408 	subpassDesc.pPreserveAttachments	= DE_NULL;
409 
410 	deMemset(&renderPassParams, 0xcd, sizeof(renderPassParams));
411 	renderPassParams.sType				= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
412 	renderPassParams.pNext				= DE_NULL;
413 	renderPassParams.flags				= 0;
414 	renderPassParams.attachmentCount	= 1;
415 	renderPassParams.pAttachments		= &colorAttachmentDesc;
416 	renderPassParams.subpassCount		= 1;
417 	renderPassParams.pSubpasses			= &subpassDesc;
418 	renderPassParams.dependencyCount	= 0;
419 	renderPassParams.pDependencies		= DE_NULL;
420 
421 	renderPass = createRenderPass(vkd, device, &renderPassParams);
422 }
423 
424 struct ShaderDescParams
425 {
426 	VkShaderModule			shaderModule;
427 	VkShaderStageFlagBits	stage;
428 };
429 
430 struct VertexDesc
431 {
432 	deUint32	location;
433 	VkFormat	format;
434 	deUint32	stride;
435 	deUint32	offset;
436 };
437 
createVertexInfo(const vector<VertexDesc> & vertexDesc,vector<VkVertexInputBindingDescription> & bindingList,vector<VkVertexInputAttributeDescription> & attrList,VkPipelineVertexInputStateCreateInfo & vertexInputState)438 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
439 {
440 	for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
441 	{
442 		deUint32							bindingId = 0;
443 		VkVertexInputBindingDescription		bindingDesc;
444 		VkVertexInputAttributeDescription	attrDesc;
445 
446 		bindingDesc.binding		= bindingId;
447 		bindingDesc.stride		= vertDescIter->stride;
448 		bindingDesc.inputRate	= VK_VERTEX_INPUT_RATE_VERTEX;
449 		bindingList.push_back(bindingDesc);
450 
451 		attrDesc.location		= vertDescIter->location;
452 		attrDesc.binding		= bindingId;
453 		attrDesc.format			= vertDescIter->format;
454 		attrDesc.offset			= vertDescIter->offset;
455 		attrList.push_back(attrDesc);
456 
457 		bindingId++;
458 	}
459 
460 	deMemset(&vertexInputState, 0xcd, sizeof(vertexInputState));
461 	vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
462 	vertexInputState.pNext = DE_NULL;
463 	vertexInputState.flags = 0u;
464 	vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
465 	vertexInputState.pVertexBindingDescriptions = &bindingList[0];
466 	vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
467 	vertexInputState.pVertexAttributeDescriptions = &attrList[0];
468 }
469 
createCommandBuffer(const DeviceInterface & deviceInterface,const VkDevice device,const deUint32 queueFamilyNdx,vk::Move<VkCommandBuffer> * commandBufferRef,vk::Move<VkCommandPool> * commandPoolRef)470 void createCommandBuffer (const DeviceInterface& deviceInterface, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef, vk::Move<VkCommandPool>* commandPoolRef)
471 {
472 	vk::Move<VkCommandPool>		commandPool;
473 	VkCommandBufferAllocateInfo	commandBufferInfo;
474 	VkCommandBuffer				commandBuffer;
475 
476 	commandPool = createCommandPool(deviceInterface, device, 0u, queueFamilyNdx);
477 
478 	deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo));
479 	commandBufferInfo.sType					= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
480 	commandBufferInfo.pNext					= DE_NULL;
481 	commandBufferInfo.commandPool			= commandPool.get();
482 	commandBufferInfo.level					= VK_COMMAND_BUFFER_LEVEL_PRIMARY;
483 	commandBufferInfo.commandBufferCount	= 1;
484 
485 	VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
486 	*commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get()));
487 	*commandPoolRef = commandPool;
488 }
489 
createFences(const DeviceInterface & deviceInterface,VkDevice device,bool signaled,deUint32 numFences,VkFence * fence)490 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
491 {
492 	VkFenceCreateInfo		fenceState;
493 	VkFenceCreateFlags		signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
494 
495 	deMemset(&fenceState, 0xcd, sizeof(fenceState));
496 	fenceState.sType		= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
497 	fenceState.pNext		= DE_NULL;
498 	fenceState.flags		= signalFlag;
499 
500 	for (deUint32 ndx = 0; ndx < numFences; ndx++)
501 		VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
502 }
503 
destroyFences(const DeviceInterface & deviceInterface,VkDevice device,deUint32 numFences,VkFence * fence)504 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
505 {
506 	for (deUint32 ndx = 0; ndx < numFences; ndx++)
507 		deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
508 }
509 
510 struct RenderInfo
511 {
512 	deInt32							width;
513 	deInt32							height;
514 	deUint32						vertexBufferSize;
515 	VkBuffer						vertexBuffer;
516 	VkImage							image;
517 	VkCommandBuffer					commandBuffer;
518 	VkRenderPass					renderPass;
519 	VkFramebuffer					framebuffer;
520 	VkPipeline						pipeline;
521 	deUint32						mipLevels;
522 	const deUint32*					queueFamilyNdxList;
523 	deUint32						queueFamilyNdxCount;
524 	bool							waitEvent;
525 	VkEvent							event;
526 	vector<VkImageMemoryBarrier>*	barriers;
527 };
528 
recordRenderPass(const DeviceInterface & deviceInterface,const RenderInfo & renderInfo)529 void  recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo)
530 {
531 	const VkDeviceSize					bindingOffset			= 0;
532 	VkImageMemoryBarrier				renderBarrier;
533 
534 	if (renderInfo.waitEvent)
535 		deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
536 
537 	beginRenderPass(deviceInterface, renderInfo.commandBuffer, renderInfo.renderPass, renderInfo.framebuffer, makeRect2D(0, 0, renderInfo.width, renderInfo.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
538 	deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
539 	deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
540 	deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
541 	endRenderPass(deviceInterface, renderInfo.commandBuffer);
542 
543 	deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier));
544 	renderBarrier.sType								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
545 	renderBarrier.pNext								= DE_NULL;
546 	renderBarrier.srcAccessMask						= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
547 	renderBarrier.dstAccessMask						= VK_ACCESS_TRANSFER_READ_BIT;
548 	renderBarrier.oldLayout							= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
549 	renderBarrier.newLayout							= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
550 	renderBarrier.srcQueueFamilyIndex				= renderInfo.queueFamilyNdxList[0];
551 	renderBarrier.dstQueueFamilyIndex				= renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
552 	renderBarrier.image								= renderInfo.image;
553 	renderBarrier.subresourceRange.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
554 	renderBarrier.subresourceRange.baseMipLevel		= 0;
555 	renderBarrier.subresourceRange.levelCount		= renderInfo.mipLevels;
556 	renderBarrier.subresourceRange.baseArrayLayer	= 0;
557 	renderBarrier.subresourceRange.layerCount		= 1;
558 	renderInfo.barriers->push_back(renderBarrier);
559 }
560 
561 struct TransferInfo
562 {
563 	VkCommandBuffer					commandBuffer;
564 	deUint32						width;
565 	deUint32						height;
566 	VkImage							image;
567 	VkBuffer						buffer;
568 	VkDeviceSize					size;
569 	deUint32						mipLevel;
570 	VkOffset3D						imageOffset;
571 	vector<VkBufferMemoryBarrier>*	barriers;
572 };
573 
copyToCPU(const DeviceInterface & vkd,TransferInfo * transferInfo)574 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo)
575 {
576 	VkBufferImageCopy	copyState;
577 
578 	copyState.bufferOffset						= 0;
579 	copyState.bufferRowLength					= transferInfo->width;
580 	copyState.bufferImageHeight					= transferInfo->height;
581 	copyState.imageSubresource.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
582 	copyState.imageSubresource.mipLevel			= transferInfo->mipLevel;
583 	copyState.imageSubresource.baseArrayLayer	= 0;
584 	copyState.imageSubresource.layerCount		= 1;
585 	copyState.imageOffset						= transferInfo->imageOffset;
586 	copyState.imageExtent.width					= (deInt32)(transferInfo->width);
587 	copyState.imageExtent.height				= (deInt32)(transferInfo->height);
588 	copyState.imageExtent.depth					= 1;
589 
590 	vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, &copyState);
591 
592 	{
593 		VkBufferMemoryBarrier	bufferBarrier;
594 		deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier));
595 		bufferBarrier.sType					= VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
596 		bufferBarrier.pNext					= DE_NULL;
597 		bufferBarrier.srcAccessMask			= VK_ACCESS_TRANSFER_WRITE_BIT;
598 		bufferBarrier.dstAccessMask			= VK_ACCESS_HOST_READ_BIT;
599 		bufferBarrier.srcQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
600 		bufferBarrier.dstQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
601 		bufferBarrier.buffer				= transferInfo->buffer;
602 		bufferBarrier.offset				= 0;
603 		bufferBarrier.size					= transferInfo->size;
604 		transferInfo->barriers->push_back(bufferBarrier);
605 	}
606 }
607 
608 struct TestContext
609 {
610 	const DeviceInterface&		vkd;
611 	const VkDevice				device;
612 	const deUint32				queueFamilyIndex;
613 	const BinaryCollection&		binaryCollection;
614 	Allocator&					allocator;
615 	de::SharedPtr<vk::ResourceInterface>	resourceInterface;
616 
617 	const tcu::Vec4*			vertices;
618 	deUint32					numVertices;
619 	tcu::IVec2					renderDimension;
620 	VkFence						fences[2];
621 	VkDeviceSize				renderSize;
622 	MovePtr<Allocation>			renderReadBuffer;
623 	MovePtr<Allocation>			vertexBufferAllocation;
624 	vk::Move<VkBuffer>			vertexBuffer;
625 	vk::Move<VkBuffer>			renderBuffer;
626 	bool						waitEvent;
627 	VkEvent						event;
628 	vk::Move<VkImage>			image;
629 	vk::Move<VkImageView>		imageView;
630 	vk::Move<VkFramebuffer>		framebuffer;
631 	vk::Move<VkCommandPool>		commandPool;
632 	vk::Move<VkCommandBuffer>	cmdBuffer;
633 	vk::Move<VkRenderPass>		renderPass;
634 	vk::Move<VkPipelineCache>	pipelineCache;
635 	vk::Move<VkPipeline>		pipeline;
636 	MovePtr<Allocation>			imageAllocation;
637 
TestContextvkt::synchronization::__anon929fae3a0111::TestContext638 	TestContext (const DeviceInterface&					vkd_,
639 				 const VkDevice							device_,
640 				 deUint32								queueFamilyIndex_,
641 				 const BinaryCollection&				binaryCollection_,
642 				 Allocator&								allocator_,
643 				 de::SharedPtr<vk::ResourceInterface>	resourceInterface_)
644 		: vkd				(vkd_)
645 		, device			(device_)
646 		, queueFamilyIndex	(queueFamilyIndex_)
647 		, binaryCollection	(binaryCollection_)
648 		, allocator			(allocator_)
649 		, resourceInterface	(resourceInterface_)
650 		, vertices			(0)
651 		, numVertices		(0)
652 		, renderSize		(0)
653 		, waitEvent			(false)
654 	{
655 		createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences);
656 	}
657 
~TestContextvkt::synchronization::__anon929fae3a0111::TestContext658 	~TestContext()
659 	{
660 		destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences);
661 	}
662 };
663 
generateWork(TestContext & testContext)664 void generateWork (TestContext& testContext)
665 {
666 	const DeviceInterface&						deviceInterface		= testContext.vkd;
667 	const deUint32								queueFamilyNdx		= testContext.queueFamilyIndex;
668 
669 	// \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted
670 	//       as pipeline has been constructed.
671 	const vk::Unique<VkShaderModule>			vertShaderModule	(createShaderModule(deviceInterface,
672 																						testContext.device,
673 																						testContext.binaryCollection.get("glslvert"),
674 																						(VkShaderModuleCreateFlags)0));
675 
676 	const vk::Unique<VkShaderModule>			fragShaderModule	(createShaderModule(deviceInterface,
677 																						testContext.device,
678 																						testContext.binaryCollection.get("glslfrag"),
679 																						(VkShaderModuleCreateFlags)0));
680 	const VkPipelineShaderStageCreateInfo		shaderStageParams[]	=
681 	{
682 		{
683 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
684 			DE_NULL,
685 			(VkPipelineShaderStageCreateFlags)0,
686 			VK_SHADER_STAGE_VERTEX_BIT,
687 			*vertShaderModule,
688 			"main",
689 			(const VkSpecializationInfo*)DE_NULL,
690 		},
691 		{
692 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
693 			DE_NULL,
694 			(VkPipelineShaderStageCreateFlags)0,
695 			VK_SHADER_STAGE_FRAGMENT_BIT,
696 			*fragShaderModule,
697 			"main",
698 			(const VkSpecializationInfo*)DE_NULL,
699 		}
700 	};
701 
702 	vk::Move<VkPipelineLayout>					layout;
703 	vector<ShaderDescParams>					shaderDescParams;
704 	VertexDesc									vertexDesc;
705 	vector<VertexDesc>							vertexDescList;
706 	vector<VkVertexInputAttributeDescription>	attrList;
707 	vector<VkBufferMemoryBarrier>				bufferMemoryBarrier;
708 	deUint32									memoryBarrierNdx;
709 	deUint32									bufferMemoryBarrierNdx;
710 	deUint32									imageMemoryBarrierNdx;
711 	vector<VkVertexInputBindingDescription>		bindingList;
712 	VkPipelineVertexInputStateCreateInfo		vertexInputState;
713 	VkPipelineInputAssemblyStateCreateInfo		inputAssemblyState;
714 	VkPipelineDepthStencilStateCreateInfo		depthStencilState;
715 	VkPipelineColorBlendAttachmentState			blendAttachment;
716 	VkPipelineColorBlendStateCreateInfo			blendState;
717 	VkPipelineLayoutCreateInfo					pipelineLayoutState;
718 	VkGraphicsPipelineCreateInfo				pipelineState;
719 	VkPipelineCacheCreateInfo					cacheState;
720 	VkViewport									viewport;
721 	VkPipelineViewportStateCreateInfo			viewportInfo;
722 	VkRect2D									scissor;
723 	BufferParameters							bufferParameters;
724 	Buffer										buffer;
725 	RenderInfo									renderInfo;
726 	ImageParameters								imageParameters;
727 	Image										image;
728 	VkPipelineRasterizationStateCreateInfo		rasterState;
729 	VkPipelineMultisampleStateCreateInfo		multisampleState;
730 	VkFramebufferCreateInfo						fbState;
731 	VkCommandBufferBeginInfo					commandBufRecordState;
732 	VkCommandBufferInheritanceInfo				inheritanceInfo;
733 	RenderPassParameters						renderPassParameters;
734 	TransferInfo								transferInfo;
735 	vector<void*>								barrierList;
736 	VkExtent3D									extent;
737 	vector<VkMemoryBarrier>						memoryBarriers;
738 	vector<VkBufferMemoryBarrier>				bufferBarriers;
739 	vector<VkImageMemoryBarrier>				imageBarriers;
740 
741 	memoryBarrierNdx			= 0;
742 	bufferMemoryBarrierNdx		= 0;
743 	imageMemoryBarrierNdx		= 0;
744 	buffer.memoryBarrier.resize(memoryBarrierNdx);
745 	bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
746 	image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
747 
748 	memoryBarriers.resize(0);
749 	bufferBarriers.resize(0);
750 	imageBarriers.resize(0);
751 
752 	bufferParameters.memory					= testContext.vertices;
753 	bufferParameters.size					= testContext.numVertices * sizeof(tcu::Vec4);
754 	bufferParameters.usage					= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
755 	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
756 	bufferParameters.queueFamilyCount		= 1;
757 	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
758 	bufferParameters.inputBarrierFlags		= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
759 	createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
760 	testContext.vertexBufferAllocation		= buffer.allocation;
761 	testContext.vertexBuffer				= buffer.buffer;
762 
763 	bufferParameters.memory					= DE_NULL;
764 	bufferParameters.size					= testContext.renderSize;
765 	bufferParameters.usage					= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
766 	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
767 	bufferParameters.queueFamilyCount		= 1;
768 	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
769 	bufferParameters.inputBarrierFlags		= 0;
770 	createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
771 	testContext.renderReadBuffer			= buffer.allocation;
772 	testContext.renderBuffer				= buffer.buffer;
773 
774 	extent.width							= testContext.renderDimension.x();
775 	extent.height							= testContext.renderDimension.y();
776 	extent.depth							= 1;
777 
778 	imageParameters.imageType				= VK_IMAGE_TYPE_2D;
779 	imageParameters.format					= VK_FORMAT_R8G8B8A8_UNORM;
780 	imageParameters.extent3D				= extent;
781 	imageParameters.mipLevels				= 1;
782 	imageParameters.samples					= VK_SAMPLE_COUNT_1_BIT;
783 	imageParameters.tiling					= VK_IMAGE_TILING_OPTIMAL;
784 	imageParameters.usage					= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
785 	imageParameters.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
786 	imageParameters.queueFamilyCount		= 1;
787 	imageParameters.queueFamilyNdxList		= &queueFamilyNdx;
788 	imageParameters.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
789 	imageParameters.finalLayout				= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
790 	imageParameters.barrierInputMask		= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
791 	createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any);
792 	testContext.imageAllocation				= image.allocation;
793 	testContext.image						= image.image;
794 
795 	for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx)
796 		imageBarriers.push_back(image.imageMemoryBarrier[ndx]);
797 
798 	renderPassParameters.colorFormat		= VK_FORMAT_R8G8B8A8_UNORM;
799 	renderPassParameters.colorSamples		= VK_SAMPLE_COUNT_1_BIT;
800 	createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass);
801 
802 	vertexDesc.location = 0;
803 	vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
804 	vertexDesc.stride = sizeof(tcu::Vec4);
805 	vertexDesc.offset = 0;
806 	vertexDescList.push_back(vertexDesc);
807 
808 	createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
809 
810 	deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState));
811 	inputAssemblyState.sType					= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
812 	inputAssemblyState.pNext					= DE_NULL;
813 	inputAssemblyState.flags					= 0u;
814 	inputAssemblyState.topology					= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
815 	inputAssemblyState.primitiveRestartEnable	= false;
816 
817 	viewport.x									= 0;
818 	viewport.y									= 0;
819 	viewport.width								= (float)testContext.renderDimension.x();
820 	viewport.height								= (float)testContext.renderDimension.y();
821 	viewport.minDepth							= 0;
822 	viewport.maxDepth							= 1;
823 
824 	scissor.offset.x							= 0;
825 	scissor.offset.y							= 0;
826 	scissor.extent.width						= testContext.renderDimension.x();
827 	scissor.extent.height						= testContext.renderDimension.y();
828 
829 	deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo));
830 	viewportInfo.sType							= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
831 	viewportInfo.pNext							= DE_NULL;
832 	viewportInfo.flags							= 0;
833 	viewportInfo.viewportCount					= 1;
834 	viewportInfo.pViewports						= &viewport;
835 	viewportInfo.scissorCount					= 1;
836 	viewportInfo.pScissors						= &scissor;
837 
838 	deMemset(&rasterState, 0xcd, sizeof(rasterState));
839 	rasterState.sType							= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
840 	rasterState.pNext							= DE_NULL;
841 	rasterState.flags							= 0;
842 	rasterState.depthClampEnable				= VK_FALSE;
843 	rasterState.rasterizerDiscardEnable			= VK_FALSE;
844 	rasterState.polygonMode						= VK_POLYGON_MODE_FILL;
845 	rasterState.cullMode						= VK_CULL_MODE_NONE;
846 	rasterState.frontFace						= VK_FRONT_FACE_COUNTER_CLOCKWISE;
847 	rasterState.depthBiasEnable					= VK_FALSE;
848 	rasterState.lineWidth						= 1;
849 
850 	deMemset(&multisampleState, 0xcd, sizeof(multisampleState));
851 	multisampleState.sType						= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
852 	multisampleState.pNext						= DE_NULL;
853 	multisampleState.flags						= 0;
854 	multisampleState.rasterizationSamples		= VK_SAMPLE_COUNT_1_BIT;
855 	multisampleState.sampleShadingEnable		= VK_FALSE;
856 	multisampleState.pSampleMask				= DE_NULL;
857 	multisampleState.alphaToCoverageEnable		= VK_FALSE;
858 	multisampleState.alphaToOneEnable			= VK_FALSE;
859 
860 	deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState));
861 	depthStencilState.sType						= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
862 	depthStencilState.pNext						= DE_NULL;
863 	depthStencilState.flags						= 0;
864 	depthStencilState.depthTestEnable			= VK_FALSE;
865 	depthStencilState.depthWriteEnable			= VK_FALSE;
866 	depthStencilState.depthCompareOp			= VK_COMPARE_OP_ALWAYS;
867 	depthStencilState.depthBoundsTestEnable		= VK_FALSE;
868 	depthStencilState.stencilTestEnable			= VK_FALSE;
869 	depthStencilState.front.failOp				= VK_STENCIL_OP_KEEP;
870 	depthStencilState.front.passOp				= VK_STENCIL_OP_KEEP;
871 	depthStencilState.front.depthFailOp			= VK_STENCIL_OP_KEEP;
872 	depthStencilState.front.compareOp			= VK_COMPARE_OP_ALWAYS;
873 	depthStencilState.front.compareMask			= 0u;
874 	depthStencilState.front.writeMask			= 0u;
875 	depthStencilState.front.reference			= 0u;
876 	depthStencilState.back						= depthStencilState.front;
877 
878 	deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment));
879 	blendAttachment.blendEnable					= VK_FALSE;
880 	blendAttachment.srcColorBlendFactor			= VK_BLEND_FACTOR_ZERO;
881 	blendAttachment.srcAlphaBlendFactor			= VK_BLEND_FACTOR_ZERO;
882 	blendAttachment.dstColorBlendFactor			= VK_BLEND_FACTOR_ZERO;
883 	blendAttachment.dstAlphaBlendFactor			= VK_BLEND_FACTOR_ZERO;
884 	blendAttachment.colorBlendOp				= VK_BLEND_OP_ADD;
885 	blendAttachment.alphaBlendOp				= VK_BLEND_OP_ADD;
886 	blendAttachment.colorWriteMask				= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
887 
888 	deMemset(&blendState, 0xcd, sizeof(blendState));
889 	blendState.sType							= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
890 	blendState.pNext							= DE_NULL;
891 	blendState.flags							= 0;
892 	blendState.logicOpEnable					= VK_FALSE;
893 	blendState.logicOp							= VK_LOGIC_OP_COPY;
894 	blendState.attachmentCount					= 1;
895 	blendState.pAttachments						= &blendAttachment;
896 
897 	deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState));
898 	pipelineLayoutState.sType					= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
899 	pipelineLayoutState.pNext					= DE_NULL;
900 	pipelineLayoutState.flags					= 0;
901 	pipelineLayoutState.setLayoutCount			= 0;
902 	pipelineLayoutState.pSetLayouts				= DE_NULL;
903 	pipelineLayoutState.pushConstantRangeCount	= 0;
904 	pipelineLayoutState.pPushConstantRanges		= DE_NULL;
905 	layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL);
906 
907 	deMemset(&pipelineState, 0xcd, sizeof(pipelineState));
908 	pipelineState.sType							= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
909 	pipelineState.pNext							= DE_NULL;
910 	pipelineState.flags							= 0;
911 	pipelineState.stageCount					= DE_LENGTH_OF_ARRAY(shaderStageParams);
912 	pipelineState.pStages						= &shaderStageParams[0];
913 	pipelineState.pVertexInputState				= &vertexInputState;
914 	pipelineState.pInputAssemblyState			= &inputAssemblyState;
915 	pipelineState.pTessellationState			= DE_NULL;
916 	pipelineState.pViewportState				= &viewportInfo;
917 	pipelineState.pRasterizationState			= &rasterState;
918 	pipelineState.pMultisampleState				= &multisampleState;
919 	pipelineState.pDepthStencilState			= &depthStencilState;
920 	pipelineState.pColorBlendState				= &blendState;
921 	pipelineState.pDynamicState					= (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
922 	pipelineState.layout						= layout.get();
923 	pipelineState.renderPass					= testContext.renderPass.get();
924 	pipelineState.subpass						= 0;
925 	pipelineState.basePipelineHandle			= DE_NULL;
926 	pipelineState.basePipelineIndex				= 0;
927 
928 	deMemset(&cacheState, 0xcd, sizeof(cacheState));
929 	cacheState.sType							= VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
930 	cacheState.pNext							= DE_NULL;
931 #ifndef CTS_USES_VULKANSC
932 	cacheState.flags							= (VkPipelineCacheCreateFlags)0u;
933 	cacheState.initialDataSize					= 0;
934 	cacheState.pInitialData						= DE_NULL;
935 #else
936 	cacheState.flags							= VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT;
937 	cacheState.initialDataSize					= testContext.resourceInterface->getCacheDataSize();
938 	cacheState.pInitialData						= testContext.resourceInterface->getCacheData();
939 #endif
940 
941 	testContext.pipelineCache					= createPipelineCache(deviceInterface, testContext.device, &cacheState);
942 	testContext.pipeline						= createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState);
943 
944 	deMemset(&fbState, 0xcd, sizeof(fbState));
945 	fbState.sType								= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
946 	fbState.pNext								= DE_NULL;
947 	fbState.flags								= 0;
948 	fbState.renderPass							= testContext.renderPass.get();
949 	fbState.attachmentCount						= 1;
950 	fbState.pAttachments						= &image.imageView.get();
951 	fbState.width								= (deUint32)testContext.renderDimension.x();
952 	fbState.height								= (deUint32)testContext.renderDimension.y();
953 	fbState.layers								= 1;
954 
955 	testContext.framebuffer	= createFramebuffer(deviceInterface, testContext.device, &fbState);
956 	testContext.imageView	= image.imageView;
957 
958 	deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo));
959 	inheritanceInfo.sType						= VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
960 	inheritanceInfo.pNext						= DE_NULL;
961 	inheritanceInfo.renderPass					= testContext.renderPass.get();
962 	inheritanceInfo.subpass						= 0;
963 	inheritanceInfo.framebuffer					= *testContext.framebuffer;
964 	inheritanceInfo.occlusionQueryEnable		= VK_FALSE;
965 	inheritanceInfo.queryFlags					= 0u;
966 	inheritanceInfo.pipelineStatistics			= 0u;
967 
968 	deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState));
969 	commandBufRecordState.sType					= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
970 	commandBufRecordState.pNext					= DE_NULL;
971 	commandBufRecordState.flags					= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
972 	commandBufRecordState.pInheritanceInfo		= &inheritanceInfo;
973 	VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
974 
975 	deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
976 										VK_PIPELINE_STAGE_HOST_BIT,
977 										VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
978 										false,
979 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
980 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
981 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
982 
983 	memoryBarriers.resize(0);
984 	bufferBarriers.resize(0);
985 	imageBarriers.resize(0);
986 
987 	renderInfo.width				= testContext.renderDimension.x();
988 	renderInfo.height				= testContext.renderDimension.y();
989 	renderInfo.vertexBufferSize		= testContext.numVertices;
990 	renderInfo.vertexBuffer			= testContext.vertexBuffer.get();
991 	renderInfo.image				= testContext.image.get();
992 	renderInfo.commandBuffer		= testContext.cmdBuffer.get();
993 	renderInfo.renderPass			= testContext.renderPass.get();
994 	renderInfo.framebuffer			= *testContext.framebuffer;
995 	renderInfo.pipeline				= *testContext.pipeline;
996 	renderInfo.mipLevels			= 1;
997 	renderInfo.queueFamilyNdxList	= &queueFamilyNdx;
998 	renderInfo.queueFamilyNdxCount	= 1;
999 	renderInfo.waitEvent			= testContext.waitEvent;
1000 	renderInfo.event				= testContext.event;
1001 	renderInfo.barriers				= &imageBarriers;
1002 	recordRenderPass(deviceInterface, renderInfo);
1003 
1004 	deviceInterface.cmdPipelineBarrier(	renderInfo.commandBuffer,
1005 										VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1006 										VK_PIPELINE_STAGE_TRANSFER_BIT,
1007 										false,
1008 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
1009 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
1010 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
1011 
1012 	memoryBarriers.resize(0);
1013 	bufferBarriers.resize(0);
1014 	imageBarriers.resize(0);
1015 
1016 	transferInfo.commandBuffer		= renderInfo.commandBuffer;
1017 	transferInfo.width				= testContext.renderDimension.x();
1018 	transferInfo.height				= testContext.renderDimension.y();
1019 	transferInfo.image				= renderInfo.image;
1020 	transferInfo.buffer				= testContext.renderBuffer.get();
1021 	transferInfo.size				= testContext.renderSize;
1022 	transferInfo.mipLevel			= 0;
1023 	transferInfo.imageOffset.x		= 0;
1024 	transferInfo.imageOffset.y		= 0;
1025 	transferInfo.imageOffset.z		= 0;
1026 	transferInfo.barriers			= &bufferBarriers;
1027 	copyToCPU(deviceInterface, &transferInfo);
1028 
1029 	deviceInterface.cmdPipelineBarrier(	transferInfo.commandBuffer,
1030 										VK_PIPELINE_STAGE_TRANSFER_BIT,
1031 										VK_PIPELINE_STAGE_HOST_BIT,
1032 										false,
1033 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
1034 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
1035 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
1036 
1037 	memoryBarriers.resize(0);
1038 	bufferBarriers.resize(0);
1039 	imageBarriers.resize(0);
1040 
1041 	endCommandBuffer(deviceInterface, transferInfo.commandBuffer);
1042 }
1043 
testFences(Context & context)1044 tcu::TestStatus testFences (Context& context)
1045 {
1046 	TestLog&					log					= context.getTestContext().getLog();
1047 	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
1048 	const VkQueue				queue				= context.getUniversalQueue();
1049 	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
1050 	VkDevice					device				= context.getDevice();
1051 	VkResult					waitStatus;
1052 	VkResult					fenceStatus;
1053 	TestContext					testContext			(deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator(), context.getResourceInterface());
1054 	void*						resultImage;
1055 
1056 	const tcu::Vec4				vertices[]			=
1057 	{
1058 		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
1059 		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
1060 		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1061 	};
1062 
1063 	testContext.vertices = vertices;
1064 	testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1065 	testContext.renderDimension = tcu::IVec2(256, 256);
1066 	testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1067 
1068 	createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1069 	generateWork(testContext);
1070 
1071 	// Default status is unsignaled
1072 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1073 	if (fenceStatus != VK_NOT_READY)
1074 	{
1075 		log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1076 		return tcu::TestStatus::fail("Fence in incorrect state");
1077 	}
1078 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1079 	if (fenceStatus != VK_NOT_READY)
1080 	{
1081 		log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1082 		return tcu::TestStatus::fail("Fence in incorrect state");
1083 	}
1084 
1085 	VkSubmitInfo submitInfo { VK_STRUCTURE_TYPE_SUBMIT_INFO, DE_NULL, 0u, DE_NULL, DE_NULL, 1u, &testContext.cmdBuffer.get(), 0, DE_NULL };
1086 	VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1087 
1088 	// Wait with timeout = 0
1089 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u);
1090 	if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1091 	{
1092 		// Will most likely end with VK_TIMEOUT
1093 		log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1094 		return tcu::TestStatus::fail("Failed to wait for a single fence");
1095 	}
1096 
1097 	// Wait with a reasonable timeout
1098 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT);
1099 	if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1100 	{
1101 		// \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient
1102 		log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1103 		return tcu::TestStatus::fail("Failed to wait for a single fence");
1104 	}
1105 
1106 	// Wait for work on fences[0] to actually complete
1107 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max());
1108 	if (waitStatus != VK_SUCCESS)
1109 	{
1110 		log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage;
1111 		return tcu::TestStatus::fail("failed to wait for a fence");
1112 	}
1113 
1114 	// Wait until timeout on a fence that has not been submitted
1115 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1);
1116 	if (waitStatus != VK_TIMEOUT)
1117 	{
1118 		log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage;
1119 		return tcu::TestStatus::fail("failed to timeout on wait for single fence");
1120 	}
1121 
1122 	// Check that the fence is signaled after the wait
1123 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1124 	if (fenceStatus != VK_SUCCESS)
1125 	{
1126 		log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1127 		return tcu::TestStatus::fail("Fence in incorrect state");
1128 	}
1129 
1130 	invalidateAlloc(deviceInterface, device, *testContext.renderReadBuffer);
1131 	resultImage = testContext.renderReadBuffer->getHostPtr();
1132 
1133 	log << TestLog::Image(	"result",
1134 							"result",
1135 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1136 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1137 									testContext.renderDimension.x(),
1138 									testContext.renderDimension.y(),
1139 									1,
1140 									resultImage));
1141 
1142 	return TestStatus::pass("synchronization-fences passed");
1143 }
1144 
testSemaphores(Context & context,SemaphoreTestConfig config)1145 tcu::TestStatus testSemaphores (Context& context, SemaphoreTestConfig config)
1146 {
1147 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
1148 		TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
1149 
1150 	TestLog&					log					= context.getTestContext().getLog();
1151 	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
1152 	const auto					instance			= context.getInstance();
1153 	const auto&					instanceDriver		= context.getInstanceInterface();
1154 	const VkPhysicalDevice		physicalDevice		= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1155 	deUint32					queueFamilyIdx;
1156 	bool						isTimelineSemaphore	(config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE);
1157 	vk::Move<VkDevice>			device				(createTestDevice(context, config, instance, instanceDriver, &queueFamilyIdx));
1158 
1159 #ifndef CTS_USES_VULKANSC
1160 	de::MovePtr<vk::DeviceDriver>	deviceInterfacePtr = de::MovePtr<DeviceDriver>(new DeviceDriver(platformInterface, instance, *device, context.getUsedApiVersion()));
1161 #else
1162 	de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter>	deviceInterfacePtr = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(platformInterface, instance, *device, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties(), context.getUsedApiVersion()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *device));
1163 #endif // CTS_USES_VULKANSC
1164 	const DeviceDriver&			deviceDriver		= *deviceInterfacePtr;
1165 	SimpleAllocator				allocator			(deviceDriver,
1166 													 *device,
1167 													 getPhysicalDeviceMemoryProperties(instanceDriver, physicalDevice));
1168 	const VkQueue				queue[2]			=
1169 	{
1170 		getDeviceQueue(deviceDriver, *device, queueFamilyIdx, 0),
1171 		getDeviceQueue(deviceDriver, *device, queueFamilyIdx, 1)
1172 	};
1173 	VkResult							testStatus;
1174 	TestContext							testContext1				(deviceDriver, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator, context.getResourceInterface());
1175 	TestContext							testContext2				(deviceDriver, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator, context.getResourceInterface());
1176 	Unique<VkSemaphore>					semaphore					(createSemaphoreType(deviceDriver, *device, config.semaphoreType));
1177 	VkSemaphoreSubmitInfoKHR			waitSemaphoreSubmitInfo		= makeCommonSemaphoreSubmitInfo(*semaphore, 1u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
1178 	VkSemaphoreSubmitInfoKHR			signalSemaphoreSubmitInfo	= makeCommonSemaphoreSubmitInfo(*semaphore, 1u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR);
1179 
1180 	const tcu::Vec4		vertices1[]			=
1181 	{
1182 		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
1183 		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
1184 		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1185 	};
1186 
1187 	const tcu::Vec4		vertices2[]			=
1188 	{
1189 		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1190 		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1191 		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1192 	};
1193 
1194 	testContext1.vertices			= vertices1;
1195 	testContext1.numVertices		= DE_LENGTH_OF_ARRAY(vertices1);
1196 	testContext1.renderDimension	= tcu::IVec2(256, 256);
1197 	testContext1.renderSize			= sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1198 
1199 	testContext2.vertices			= vertices2;
1200 	testContext2.numVertices		= DE_LENGTH_OF_ARRAY(vertices2);
1201 	testContext2.renderDimension	= tcu::IVec2(256, 256);
1202 	testContext2.renderSize			= sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1203 
1204 	createCommandBuffer(deviceDriver, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool);
1205 	generateWork(testContext1);
1206 
1207 	createCommandBuffer(deviceDriver, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool);
1208 	generateWork(testContext2);
1209 
1210 	{
1211 		VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(testContext1.cmdBuffer.get());
1212 		SynchronizationWrapperPtr		synchronizationWrapper = getSynchronizationWrapper(config.synchronizationType, deviceDriver, isTimelineSemaphore);
1213 		synchronizationWrapper->addSubmitInfo(
1214 			0u,										// deUint32								waitSemaphoreInfoCount
1215 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
1216 			1u,										// deUint32								commandBufferInfoCount
1217 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
1218 			1u,										// deUint32								signalSemaphoreInfoCount
1219 			&signalSemaphoreSubmitInfo,				// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
1220 			DE_FALSE,
1221 			isTimelineSemaphore
1222 		);
1223 
1224 		VK_CHECK(synchronizationWrapper->queueSubmit(queue[0], testContext1.fences[0]));
1225 	}
1226 
1227 	testStatus  = deviceDriver.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max());
1228 	if (testStatus != VK_SUCCESS)
1229 	{
1230 		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1231 		return tcu::TestStatus::fail("failed to wait for a set fence");
1232 	}
1233 
1234 	invalidateAlloc(deviceDriver, device.get(), *testContext1.renderReadBuffer);
1235 	void* resultImage = testContext1.renderReadBuffer->getHostPtr();
1236 
1237 	log << TestLog::Image(	"result",
1238 							"result",
1239 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1240 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1241 									testContext1.renderDimension.x(),
1242 									testContext1.renderDimension.y(),
1243 									1,
1244 									resultImage));
1245 
1246 	// The difference between the second submit info is that it will use a unique cmd buffer.
1247 	// First submit signals a semaphore but not wait on a semaphore, the other waits on the
1248 	// semaphore but not signal it.
1249 	{
1250 		VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo	= makeCommonCommandBufferSubmitInfo(testContext2.cmdBuffer.get());
1251 		SynchronizationWrapperPtr		synchronizationWrapper	= getSynchronizationWrapper(config.synchronizationType, deviceDriver, isTimelineSemaphore);
1252 		synchronizationWrapper->addSubmitInfo(
1253 			1u,										// deUint32								waitSemaphoreInfoCount
1254 			&waitSemaphoreSubmitInfo,				// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
1255 			1u,										// deUint32								commandBufferInfoCount
1256 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
1257 			0u,										// deUint32								signalSemaphoreInfoCount
1258 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
1259 			isTimelineSemaphore
1260 		);
1261 
1262 		VK_CHECK(synchronizationWrapper->queueSubmit(queue[1], testContext2.fences[0]));
1263 	}
1264 
1265 	testStatus  = deviceDriver.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max());
1266 	if (testStatus != VK_SUCCESS)
1267 	{
1268 		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1269 		return tcu::TestStatus::fail("failed to wait for a set fence");
1270 	}
1271 
1272 	invalidateAlloc(deviceDriver, device.get(), *testContext2.renderReadBuffer);
1273 	resultImage = testContext2.renderReadBuffer->getHostPtr();
1274 
1275 	log << TestLog::Image(	"result",
1276 							"result",
1277 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1278 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1279 									testContext2.renderDimension.x(),
1280 									testContext2.renderDimension.y(),
1281 									1,
1282 									resultImage));
1283 
1284 	return tcu::TestStatus::pass("synchronization-semaphores passed");
1285 }
1286 
checkSupport(Context & context,SemaphoreTestConfig config)1287 void checkSupport(Context& context, SemaphoreTestConfig config)
1288 {
1289 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
1290 		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
1291 	if (config.synchronizationType == SynchronizationType::SYNCHRONIZATION2)
1292 		context.requireDeviceFunctionality("VK_KHR_synchronization2");
1293 }
1294 
1295 } // anonymous
1296 
createSmokeTests(tcu::TestContext & textCtx)1297 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx)
1298 {
1299 	SynchronizationType					type		(SynchronizationType::LEGACY);
1300 	de::MovePtr<tcu::TestCaseGroup>		smokeTests	(new tcu::TestCaseGroup(textCtx, "smoke"));
1301 
1302 	addFunctionCaseWithPrograms(smokeTests.get(), "fences", buildShaders, testFences);
1303 	addFunctionCaseWithPrograms(smokeTests.get(), "binary_semaphores",   checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_BINARY });
1304 	addFunctionCaseWithPrograms(smokeTests.get(), "timeline_semaphores", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_TIMELINE });
1305 
1306 	return smokeTests.release();
1307 }
1308 
createSynchronization2SmokeTests(tcu::TestContext & textCtx)1309 tcu::TestCaseGroup* createSynchronization2SmokeTests(tcu::TestContext& textCtx)
1310 {
1311 	SynchronizationType					type		(SynchronizationType::SYNCHRONIZATION2);
1312 	de::MovePtr<tcu::TestCaseGroup>		smokeTests	(new tcu::TestCaseGroup(textCtx, "smoke"));
1313 
1314 	addFunctionCaseWithPrograms(smokeTests.get(), "binary_semaphores",   checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_BINARY });
1315 	addFunctionCaseWithPrograms(smokeTests.get(), "timeline_semaphores", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_TIMELINE });
1316 
1317 	return smokeTests.release();
1318 }
1319 
1320 } // synchronization
1321 } // vkt
1322