• 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::__anon4af303600111::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 		, numVertices		(0)
609 		, waitEvent			(false)
610 	{
611 		createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences);
612 	}
613 
~TestContextvkt::synchronization::__anon4af303600111::TestContext614 	~TestContext()
615 	{
616 		destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences);
617 	}
618 };
619 
generateWork(TestContext & testContext)620 void generateWork (TestContext& testContext)
621 {
622 	const DeviceInterface&						deviceInterface		= testContext.vkd;
623 	const deUint32								queueFamilyNdx		= testContext.queueFamilyIndex;
624 
625 	// \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted
626 	//       as pipeline has been constructed.
627 	const vk::Unique<VkShaderModule>			vertShaderModule	(createShaderModule(deviceInterface,
628 																						testContext.device,
629 																						testContext.binaryCollection.get("glslvert"),
630 																						(VkShaderModuleCreateFlags)0));
631 
632 	const vk::Unique<VkShaderModule>			fragShaderModule	(createShaderModule(deviceInterface,
633 																						testContext.device,
634 																						testContext.binaryCollection.get("glslfrag"),
635 																						(VkShaderModuleCreateFlags)0));
636 	const VkPipelineShaderStageCreateInfo		shaderStageParams[]	=
637 	{
638 		{
639 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
640 			DE_NULL,
641 			(VkPipelineShaderStageCreateFlags)0,
642 			VK_SHADER_STAGE_VERTEX_BIT,
643 			*vertShaderModule,
644 			"main",
645 			(const VkSpecializationInfo*)DE_NULL,
646 		},
647 		{
648 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
649 			DE_NULL,
650 			(VkPipelineShaderStageCreateFlags)0,
651 			VK_SHADER_STAGE_FRAGMENT_BIT,
652 			*fragShaderModule,
653 			"main",
654 			(const VkSpecializationInfo*)DE_NULL,
655 		}
656 	};
657 
658 	vk::Move<VkPipelineLayout>					layout;
659 	vector<ShaderDescParams>					shaderDescParams;
660 	VertexDesc									vertexDesc;
661 	vector<VertexDesc>							vertexDescList;
662 	vector<VkVertexInputAttributeDescription>	attrList;
663 	vector<VkBufferMemoryBarrier>				bufferMemoryBarrier;
664 	deUint32									memoryBarrierNdx;
665 	deUint32									bufferMemoryBarrierNdx;
666 	deUint32									imageMemoryBarrierNdx;
667 	vector<VkVertexInputBindingDescription>		bindingList;
668 	VkPipelineVertexInputStateCreateInfo		vertexInputState;
669 	VkPipelineInputAssemblyStateCreateInfo		inputAssemblyState;
670 	VkPipelineDepthStencilStateCreateInfo		depthStencilState;
671 	VkPipelineColorBlendAttachmentState			blendAttachment;
672 	VkPipelineColorBlendStateCreateInfo			blendState;
673 	VkPipelineLayoutCreateInfo					pipelineLayoutState;
674 	VkGraphicsPipelineCreateInfo				pipelineState;
675 	VkPipelineCacheCreateInfo					cacheState;
676 	VkViewport									viewport;
677 	VkPipelineViewportStateCreateInfo			viewportInfo;
678 	VkRect2D									scissor;
679 	BufferParameters							bufferParameters;
680 	Buffer										buffer;
681 	RenderInfo									renderInfo;
682 	ImageParameters								imageParameters;
683 	Image										image;
684 	VkPipelineRasterizationStateCreateInfo		rasterState;
685 	VkPipelineMultisampleStateCreateInfo		multisampleState;
686 	VkFramebufferCreateInfo						fbState;
687 	VkCommandBufferBeginInfo					commandBufRecordState;
688 	VkCommandBufferInheritanceInfo				inheritanceInfo;
689 	RenderPassParameters						renderPassParameters;
690 	TransferInfo								transferInfo;
691 	vector<void*>								barrierList;
692 	VkExtent3D									extent;
693 	vector<VkMemoryBarrier>						memoryBarriers;
694 	vector<VkBufferMemoryBarrier>				bufferBarriers;
695 	vector<VkImageMemoryBarrier>				imageBarriers;
696 
697 	memoryBarrierNdx			= 0;
698 	bufferMemoryBarrierNdx		= 0;
699 	imageMemoryBarrierNdx		= 0;
700 	buffer.memoryBarrier.resize(memoryBarrierNdx);
701 	bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
702 	image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
703 
704 	memoryBarriers.resize(0);
705 	bufferBarriers.resize(0);
706 	imageBarriers.resize(0);
707 
708 	bufferParameters.memory					= testContext.vertices;
709 	bufferParameters.size					= testContext.numVertices * sizeof(tcu::Vec4);
710 	bufferParameters.usage					= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
711 	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
712 	bufferParameters.queueFamilyCount		= 1;
713 	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
714 	bufferParameters.inputBarrierFlags		= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
715 	createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
716 	testContext.vertexBufferAllocation		= buffer.allocation;
717 	testContext.vertexBuffer				= buffer.buffer;
718 
719 	bufferParameters.memory					= DE_NULL;
720 	bufferParameters.size					= testContext.renderSize;
721 	bufferParameters.usage					= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
722 	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
723 	bufferParameters.queueFamilyCount		= 1;
724 	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
725 	bufferParameters.inputBarrierFlags		= 0;
726 	createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
727 	testContext.renderReadBuffer			= buffer.allocation;
728 	testContext.renderBuffer				= buffer.buffer;
729 
730 	extent.width							= testContext.renderDimension.x();
731 	extent.height							= testContext.renderDimension.y();
732 	extent.depth							= 1;
733 
734 	imageParameters.imageType				= VK_IMAGE_TYPE_2D;
735 	imageParameters.format					= VK_FORMAT_R8G8B8A8_UNORM;
736 	imageParameters.extent3D				= extent;
737 	imageParameters.mipLevels				= 1;
738 	imageParameters.samples					= VK_SAMPLE_COUNT_1_BIT;
739 	imageParameters.tiling					= VK_IMAGE_TILING_OPTIMAL;
740 	imageParameters.usage					= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
741 	imageParameters.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
742 	imageParameters.queueFamilyCount		= 1;
743 	imageParameters.queueFamilyNdxList		= &queueFamilyNdx;
744 	imageParameters.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
745 	imageParameters.finalLayout				= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
746 	imageParameters.barrierInputMask		= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
747 	createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any);
748 	testContext.imageAllocation				= image.allocation;
749 	testContext.image						= image.image;
750 
751 	for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx)
752 		imageBarriers.push_back(image.imageMemoryBarrier[ndx]);
753 
754 	renderPassParameters.colorFormat		= VK_FORMAT_R8G8B8A8_UNORM;
755 	renderPassParameters.colorSamples		= VK_SAMPLE_COUNT_1_BIT;
756 	createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass);
757 
758 	vertexDesc.location = 0;
759 	vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
760 	vertexDesc.stride = sizeof(tcu::Vec4);
761 	vertexDesc.offset = 0;
762 	vertexDescList.push_back(vertexDesc);
763 
764 	createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
765 
766 	deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState));
767 	inputAssemblyState.sType					= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
768 	inputAssemblyState.pNext					= DE_NULL;
769 	inputAssemblyState.flags					= 0u;
770 	inputAssemblyState.topology					= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
771 	inputAssemblyState.primitiveRestartEnable	= false;
772 
773 	viewport.x									= 0;
774 	viewport.y									= 0;
775 	viewport.width								= (float)testContext.renderDimension.x();
776 	viewport.height								= (float)testContext.renderDimension.y();
777 	viewport.minDepth							= 0;
778 	viewport.maxDepth							= 1;
779 
780 	scissor.offset.x							= 0;
781 	scissor.offset.y							= 0;
782 	scissor.extent.width						= testContext.renderDimension.x();
783 	scissor.extent.height						= testContext.renderDimension.y();
784 
785 	deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo));
786 	viewportInfo.sType							= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
787 	viewportInfo.pNext							= DE_NULL;
788 	viewportInfo.flags							= 0;
789 	viewportInfo.viewportCount					= 1;
790 	viewportInfo.pViewports						= &viewport;
791 	viewportInfo.scissorCount					= 1;
792 	viewportInfo.pScissors						= &scissor;
793 
794 	deMemset(&rasterState, 0xcd, sizeof(rasterState));
795 	rasterState.sType							= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
796 	rasterState.pNext							= DE_NULL;
797 	rasterState.flags							= 0;
798 	rasterState.depthClampEnable				= VK_FALSE;
799 	rasterState.rasterizerDiscardEnable			= VK_FALSE;
800 	rasterState.polygonMode						= VK_POLYGON_MODE_FILL;
801 	rasterState.cullMode						= VK_CULL_MODE_NONE;
802 	rasterState.frontFace						= VK_FRONT_FACE_COUNTER_CLOCKWISE;
803 	rasterState.depthBiasEnable					= VK_FALSE;
804 	rasterState.lineWidth						= 1;
805 
806 	deMemset(&multisampleState, 0xcd, sizeof(multisampleState));
807 	multisampleState.sType						= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
808 	multisampleState.pNext						= DE_NULL;
809 	multisampleState.flags						= 0;
810 	multisampleState.rasterizationSamples		= VK_SAMPLE_COUNT_1_BIT;
811 	multisampleState.sampleShadingEnable		= VK_FALSE;
812 	multisampleState.pSampleMask				= DE_NULL;
813 	multisampleState.alphaToCoverageEnable		= VK_FALSE;
814 	multisampleState.alphaToOneEnable			= VK_FALSE;
815 
816 	deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState));
817 	depthStencilState.sType						= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
818 	depthStencilState.pNext						= DE_NULL;
819 	depthStencilState.flags						= 0;
820 	depthStencilState.depthTestEnable			= VK_FALSE;
821 	depthStencilState.depthWriteEnable			= VK_FALSE;
822 	depthStencilState.depthCompareOp			= VK_COMPARE_OP_ALWAYS;
823 	depthStencilState.depthBoundsTestEnable		= VK_FALSE;
824 	depthStencilState.stencilTestEnable			= VK_FALSE;
825 	depthStencilState.front.failOp				= VK_STENCIL_OP_KEEP;
826 	depthStencilState.front.passOp				= VK_STENCIL_OP_KEEP;
827 	depthStencilState.front.depthFailOp			= VK_STENCIL_OP_KEEP;
828 	depthStencilState.front.compareOp			= VK_COMPARE_OP_ALWAYS;
829 	depthStencilState.front.compareMask			= 0u;
830 	depthStencilState.front.writeMask			= 0u;
831 	depthStencilState.front.reference			= 0u;
832 	depthStencilState.back						= depthStencilState.front;
833 
834 	deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment));
835 	blendAttachment.blendEnable					= VK_FALSE;
836 	blendAttachment.srcColorBlendFactor			= VK_BLEND_FACTOR_ZERO;
837 	blendAttachment.srcAlphaBlendFactor			= VK_BLEND_FACTOR_ZERO;
838 	blendAttachment.dstColorBlendFactor			= VK_BLEND_FACTOR_ZERO;
839 	blendAttachment.dstAlphaBlendFactor			= VK_BLEND_FACTOR_ZERO;
840 	blendAttachment.colorBlendOp				= VK_BLEND_OP_ADD;
841 	blendAttachment.alphaBlendOp				= VK_BLEND_OP_ADD;
842 	blendAttachment.colorWriteMask				= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
843 
844 	deMemset(&blendState, 0xcd, sizeof(blendState));
845 	blendState.sType							= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
846 	blendState.pNext							= DE_NULL;
847 	blendState.flags							= 0;
848 	blendState.logicOpEnable					= VK_FALSE;
849 	blendState.logicOp							= VK_LOGIC_OP_COPY;
850 	blendState.attachmentCount					= 1;
851 	blendState.pAttachments						= &blendAttachment;
852 
853 	deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState));
854 	pipelineLayoutState.sType					= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
855 	pipelineLayoutState.pNext					= DE_NULL;
856 	pipelineLayoutState.flags					= 0;
857 	pipelineLayoutState.setLayoutCount			= 0;
858 	pipelineLayoutState.pSetLayouts				= DE_NULL;
859 	pipelineLayoutState.pushConstantRangeCount	= 0;
860 	pipelineLayoutState.pPushConstantRanges		= DE_NULL;
861 	layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL);
862 
863 	deMemset(&pipelineState, 0xcd, sizeof(pipelineState));
864 	pipelineState.sType							= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
865 	pipelineState.pNext							= DE_NULL;
866 	pipelineState.flags							= 0;
867 	pipelineState.stageCount					= DE_LENGTH_OF_ARRAY(shaderStageParams);
868 	pipelineState.pStages						= &shaderStageParams[0];
869 	pipelineState.pVertexInputState				= &vertexInputState;
870 	pipelineState.pInputAssemblyState			= &inputAssemblyState;
871 	pipelineState.pTessellationState			= DE_NULL;
872 	pipelineState.pViewportState				= &viewportInfo;
873 	pipelineState.pRasterizationState			= &rasterState;
874 	pipelineState.pMultisampleState				= &multisampleState;
875 	pipelineState.pDepthStencilState			= &depthStencilState;
876 	pipelineState.pColorBlendState				= &blendState;
877 	pipelineState.pDynamicState					= (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
878 	pipelineState.layout						= layout.get();
879 	pipelineState.renderPass					= testContext.renderPass.get();
880 	pipelineState.subpass						= 0;
881 	pipelineState.basePipelineHandle			= DE_NULL;
882 	pipelineState.basePipelineIndex				= 0;
883 
884 	deMemset(&cacheState, 0xcd, sizeof(cacheState));
885 	cacheState.sType							= VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
886 	cacheState.pNext							= DE_NULL;
887 	cacheState.flags							= 0;
888 	cacheState.initialDataSize					= 0;
889 	cacheState.pInitialData						= DE_NULL;
890 
891 	testContext.pipelineCache	= createPipelineCache(deviceInterface, testContext.device, &cacheState);
892 	testContext.pipeline		= createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState);
893 
894 	deMemset(&fbState, 0xcd, sizeof(fbState));
895 	fbState.sType								= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
896 	fbState.pNext								= DE_NULL;
897 	fbState.flags								= 0;
898 	fbState.renderPass							= testContext.renderPass.get();
899 	fbState.attachmentCount						= 1;
900 	fbState.pAttachments						= &image.imageView.get();
901 	fbState.width								= (deUint32)testContext.renderDimension.x();
902 	fbState.height								= (deUint32)testContext.renderDimension.y();
903 	fbState.layers								= 1;
904 
905 	testContext.framebuffer	= createFramebuffer(deviceInterface, testContext.device, &fbState);
906 	testContext.imageView	= image.imageView;
907 
908 	deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo));
909 	inheritanceInfo.sType						= VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
910 	inheritanceInfo.pNext						= DE_NULL;
911 	inheritanceInfo.renderPass					= testContext.renderPass.get();
912 	inheritanceInfo.subpass						= 0;
913 	inheritanceInfo.framebuffer					= *testContext.framebuffer;
914 	inheritanceInfo.occlusionQueryEnable		= VK_FALSE;
915 	inheritanceInfo.queryFlags					= 0u;
916 	inheritanceInfo.pipelineStatistics			= 0u;
917 
918 	deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState));
919 	commandBufRecordState.sType					= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
920 	commandBufRecordState.pNext					= DE_NULL;
921 	commandBufRecordState.flags					= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
922 	commandBufRecordState.pInheritanceInfo		= &inheritanceInfo;
923 	VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
924 
925 	deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
926 										VK_PIPELINE_STAGE_HOST_BIT,
927 										VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
928 										false,
929 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
930 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
931 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
932 
933 	memoryBarriers.resize(0);
934 	bufferBarriers.resize(0);
935 	imageBarriers.resize(0);
936 
937 	renderInfo.width				= testContext.renderDimension.x();
938 	renderInfo.height				= testContext.renderDimension.y();
939 	renderInfo.vertexBufferSize		= testContext.numVertices;
940 	renderInfo.vertexBuffer			= testContext.vertexBuffer.get();
941 	renderInfo.image				= testContext.image.get();
942 	renderInfo.commandBuffer		= testContext.cmdBuffer.get();
943 	renderInfo.renderPass			= testContext.renderPass.get();
944 	renderInfo.framebuffer			= *testContext.framebuffer;
945 	renderInfo.pipeline				= *testContext.pipeline;
946 	renderInfo.mipLevels			= 1;
947 	renderInfo.queueFamilyNdxList	= &queueFamilyNdx;
948 	renderInfo.queueFamilyNdxCount	= 1;
949 	renderInfo.waitEvent			= testContext.waitEvent;
950 	renderInfo.event				= testContext.event;
951 	renderInfo.barriers				= &imageBarriers;
952 	recordRenderPass(deviceInterface, renderInfo);
953 
954 	deviceInterface.cmdPipelineBarrier(	renderInfo.commandBuffer,
955 										VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
956 										VK_PIPELINE_STAGE_TRANSFER_BIT,
957 										false,
958 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
959 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
960 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
961 
962 	memoryBarriers.resize(0);
963 	bufferBarriers.resize(0);
964 	imageBarriers.resize(0);
965 
966 	transferInfo.commandBuffer		= renderInfo.commandBuffer;
967 	transferInfo.width				= testContext.renderDimension.x();
968 	transferInfo.height				= testContext.renderDimension.y();
969 	transferInfo.image				= renderInfo.image;
970 	transferInfo.buffer				= testContext.renderBuffer.get();
971 	transferInfo.size				= testContext.renderSize;
972 	transferInfo.mipLevel			= 0;
973 	transferInfo.imageOffset.x		= 0;
974 	transferInfo.imageOffset.y		= 0;
975 	transferInfo.imageOffset.z		= 0;
976 	transferInfo.barriers			= &bufferBarriers;
977 	copyToCPU(deviceInterface, &transferInfo);
978 
979 	deviceInterface.cmdPipelineBarrier(	transferInfo.commandBuffer,
980 										VK_PIPELINE_STAGE_TRANSFER_BIT,
981 										VK_PIPELINE_STAGE_HOST_BIT,
982 										false,
983 										(deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
984 										(deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
985 										(deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
986 
987 	memoryBarriers.resize(0);
988 	bufferBarriers.resize(0);
989 	imageBarriers.resize(0);
990 
991 	endCommandBuffer(deviceInterface, transferInfo.commandBuffer);
992 }
993 
testFences(Context & context)994 tcu::TestStatus testFences (Context& context)
995 {
996 	TestLog&					log					= context.getTestContext().getLog();
997 	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
998 	const VkQueue				queue				= context.getUniversalQueue();
999 	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
1000 	VkDevice					device				= context.getDevice();
1001 	VkResult					waitStatus;
1002 	VkResult					fenceStatus;
1003 	TestContext					testContext			(deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator());
1004 	void*						resultImage;
1005 
1006 	const tcu::Vec4				vertices[]			=
1007 	{
1008 		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
1009 		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
1010 		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1011 	};
1012 
1013 	testContext.vertices = vertices;
1014 	testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1015 	testContext.renderDimension = tcu::IVec2(256, 256);
1016 	testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1017 
1018 	createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1019 	generateWork(testContext);
1020 
1021 	// Default status is unsignaled
1022 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1023 	if (fenceStatus != VK_NOT_READY)
1024 	{
1025 		log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1026 		return tcu::TestStatus::fail("Fence in incorrect state");
1027 	}
1028 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1029 	if (fenceStatus != VK_NOT_READY)
1030 	{
1031 		log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1032 		return tcu::TestStatus::fail("Fence in incorrect state");
1033 	}
1034 
1035 	VkSubmitInfo submitInfo { VK_STRUCTURE_TYPE_SUBMIT_INFO, DE_NULL, 0u, DE_NULL, DE_NULL, 1u, &testContext.cmdBuffer.get(), 0, DE_NULL };
1036 	VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1037 
1038 	// Wait with timeout = 0
1039 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u);
1040 	if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1041 	{
1042 		// Will most likely end with VK_TIMEOUT
1043 		log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1044 		return tcu::TestStatus::fail("Failed to wait for a single fence");
1045 	}
1046 
1047 	// Wait with a reasonable timeout
1048 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT);
1049 	if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1050 	{
1051 		// \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient
1052 		log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1053 		return tcu::TestStatus::fail("Failed to wait for a single fence");
1054 	}
1055 
1056 	// Wait for work on fences[0] to actually complete
1057 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max());
1058 	if (waitStatus != VK_SUCCESS)
1059 	{
1060 		log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage;
1061 		return tcu::TestStatus::fail("failed to wait for a fence");
1062 	}
1063 
1064 	// Wait until timeout on a fence that has not been submitted
1065 	waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1);
1066 	if (waitStatus != VK_TIMEOUT)
1067 	{
1068 		log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage;
1069 		return tcu::TestStatus::fail("failed to timeout on wait for single fence");
1070 	}
1071 
1072 	// Check that the fence is signaled after the wait
1073 	fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1074 	if (fenceStatus != VK_SUCCESS)
1075 	{
1076 		log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1077 		return tcu::TestStatus::fail("Fence in incorrect state");
1078 	}
1079 
1080 	invalidateAlloc(deviceInterface, device, *testContext.renderReadBuffer);
1081 	resultImage = testContext.renderReadBuffer->getHostPtr();
1082 
1083 	log << TestLog::Image(	"result",
1084 							"result",
1085 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1086 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1087 									testContext.renderDimension.x(),
1088 									testContext.renderDimension.y(),
1089 									1,
1090 									resultImage));
1091 
1092 	return TestStatus::pass("synchronization-fences passed");
1093 }
1094 
testSemaphores(Context & context,SemaphoreTestConfig config)1095 tcu::TestStatus testSemaphores (Context& context, SemaphoreTestConfig config)
1096 {
1097 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
1098 		TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
1099 
1100 	TestLog&					log					= context.getTestContext().getLog();
1101 	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
1102 	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
1103 	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
1104 	deUint32					queueFamilyIdx;
1105 	bool						isTimelineSemaphore	(config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE);
1106 	vk::Move<VkDevice>			device				(createTestDevice(context, config, &queueFamilyIdx));
1107 	const DeviceDriver			deviceInterface		(platformInterface, context.getInstance(), *device);
1108 	SimpleAllocator				allocator			(deviceInterface,
1109 													 *device,
1110 													 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
1111 	const VkQueue				queue[2]			=
1112 	{
1113 		getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 0),
1114 		getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 1)
1115 	};
1116 	VkResult							testStatus;
1117 	TestContext							testContext1				(deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1118 	TestContext							testContext2				(deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1119 	Unique<VkSemaphore>					semaphore					(createSemaphoreType(deviceInterface, *device, config.semaphoreType));
1120 	VkSemaphoreSubmitInfoKHR			waitSemaphoreSubmitInfo		= makeCommonSemaphoreSubmitInfo(*semaphore, 1u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
1121 	VkSemaphoreSubmitInfoKHR			signalSemaphoreSubmitInfo	= makeCommonSemaphoreSubmitInfo(*semaphore, 1u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR);
1122 
1123 	const tcu::Vec4		vertices1[]			=
1124 	{
1125 		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
1126 		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
1127 		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1128 	};
1129 
1130 	const tcu::Vec4		vertices2[]			=
1131 	{
1132 		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1133 		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1134 		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1135 	};
1136 
1137 	testContext1.vertices			= vertices1;
1138 	testContext1.numVertices		= DE_LENGTH_OF_ARRAY(vertices1);
1139 	testContext1.renderDimension	= tcu::IVec2(256, 256);
1140 	testContext1.renderSize			= sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1141 
1142 	testContext2.vertices			= vertices2;
1143 	testContext2.numVertices		= DE_LENGTH_OF_ARRAY(vertices2);
1144 	testContext2.renderDimension	= tcu::IVec2(256, 256);
1145 	testContext2.renderSize			= sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1146 
1147 	createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool);
1148 	generateWork(testContext1);
1149 
1150 	createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool);
1151 	generateWork(testContext2);
1152 
1153 	{
1154 		VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(testContext1.cmdBuffer.get());
1155 		SynchronizationWrapperPtr		synchronizationWrapper = getSynchronizationWrapper(config.synchronizationType, deviceInterface, isTimelineSemaphore);
1156 		synchronizationWrapper->addSubmitInfo(
1157 			0u,										// deUint32								waitSemaphoreInfoCount
1158 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
1159 			1u,										// deUint32								commandBufferInfoCount
1160 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
1161 			1u,										// deUint32								signalSemaphoreInfoCount
1162 			&signalSemaphoreSubmitInfo,				// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
1163 			DE_FALSE,
1164 			isTimelineSemaphore
1165 		);
1166 
1167 		VK_CHECK(synchronizationWrapper->queueSubmit(queue[0], testContext1.fences[0]));
1168 	}
1169 
1170 	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max());
1171 	if (testStatus != VK_SUCCESS)
1172 	{
1173 		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1174 		return tcu::TestStatus::fail("failed to wait for a set fence");
1175 	}
1176 
1177 	invalidateAlloc(deviceInterface, device.get(), *testContext1.renderReadBuffer);
1178 	void* resultImage = testContext1.renderReadBuffer->getHostPtr();
1179 
1180 	log << TestLog::Image(	"result",
1181 							"result",
1182 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1183 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1184 									testContext1.renderDimension.x(),
1185 									testContext1.renderDimension.y(),
1186 									1,
1187 									resultImage));
1188 
1189 	// The difference between the second submit info is that it will use a unique cmd buffer.
1190 	// First submit signals a semaphore but not wait on a semaphore, the other waits on the
1191 	// semaphore but not signal it.
1192 	{
1193 		VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo	= makeCommonCommandBufferSubmitInfo(testContext2.cmdBuffer.get());
1194 		SynchronizationWrapperPtr		synchronizationWrapper	= getSynchronizationWrapper(config.synchronizationType, deviceInterface, isTimelineSemaphore);
1195 		synchronizationWrapper->addSubmitInfo(
1196 			1u,										// deUint32								waitSemaphoreInfoCount
1197 			&waitSemaphoreSubmitInfo,				// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
1198 			1u,										// deUint32								commandBufferInfoCount
1199 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
1200 			0u,										// deUint32								signalSemaphoreInfoCount
1201 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
1202 			isTimelineSemaphore
1203 		);
1204 
1205 		VK_CHECK(synchronizationWrapper->queueSubmit(queue[1], testContext2.fences[0]));
1206 	}
1207 
1208 	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max());
1209 	if (testStatus != VK_SUCCESS)
1210 	{
1211 		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1212 		return tcu::TestStatus::fail("failed to wait for a set fence");
1213 	}
1214 
1215 	invalidateAlloc(deviceInterface, device.get(), *testContext2.renderReadBuffer);
1216 	resultImage = testContext2.renderReadBuffer->getHostPtr();
1217 
1218 	log << TestLog::Image(	"result",
1219 							"result",
1220 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1221 									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1222 									testContext2.renderDimension.x(),
1223 									testContext2.renderDimension.y(),
1224 									1,
1225 									resultImage));
1226 
1227 	return tcu::TestStatus::pass("synchronization-semaphores passed");
1228 }
1229 
checkSupport(Context & context,SemaphoreTestConfig config)1230 void checkSupport(Context& context, SemaphoreTestConfig config)
1231 {
1232 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
1233 		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
1234 	if (config.synchronizationType == SynchronizationType::SYNCHRONIZATION2)
1235 		context.requireDeviceFunctionality("VK_KHR_synchronization2");
1236 }
1237 
1238 } // anonymous
1239 
createSmokeTests(tcu::TestContext & textCtx)1240 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx)
1241 {
1242 	SynchronizationType					type		(SynchronizationType::LEGACY);
1243 	de::MovePtr<tcu::TestCaseGroup>		smokeTests	(new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests"));
1244 
1245 	addFunctionCaseWithPrograms(smokeTests.get(), "fences", "", buildShaders, testFences);
1246 	addFunctionCaseWithPrograms(smokeTests.get(), "binary_semaphores",   "", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_BINARY });
1247 	addFunctionCaseWithPrograms(smokeTests.get(), "timeline_semaphores", "", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_TIMELINE });
1248 
1249 	return smokeTests.release();
1250 }
1251 
createSynchronization2SmokeTests(tcu::TestContext & textCtx)1252 tcu::TestCaseGroup* createSynchronization2SmokeTests(tcu::TestContext& textCtx)
1253 {
1254 	SynchronizationType					type		(SynchronizationType::SYNCHRONIZATION2);
1255 	de::MovePtr<tcu::TestCaseGroup>		smokeTests	(new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests"));
1256 
1257 	addFunctionCaseWithPrograms(smokeTests.get(), "binary_semaphores",   "", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_BINARY });
1258 	addFunctionCaseWithPrograms(smokeTests.get(), "timeline_semaphores", "", checkSupport, initShaders, testSemaphores, SemaphoreTestConfig { type, VK_SEMAPHORE_TYPE_TIMELINE });
1259 
1260 	return smokeTests.release();
1261 }
1262 
1263 } // synchronization
1264 } // vkt
1265