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