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