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