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