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