Merge "Remove invalid precision macro negative tests" into nyc-dev
authorMika Isojarvi <misojarvi@google.com>
Fri, 18 Mar 2016 16:57:20 +0000 (16:57 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Fri, 18 Mar 2016 16:57:20 +0000 (16:57 +0000)
Android.mk
android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/CMakeLists.txt
external/vulkancts/modules/vulkan/vktSynchronization.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/vktSynchronization.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/vktTestPackage.cpp
modules/gles31/functional/es31fNegativeShaderApiTests.cpp

index e02deff..3aff2a3 100644 (file)
@@ -713,6 +713,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/dynamic_state/vktDynamicStateGeneralTests.cpp \
        external/vulkancts/modules/vulkan/dynamic_state/vktDynamicStateImageObjectUtil.cpp \
        external/vulkancts/modules/vulkan/vktTestPackage.cpp \
+       external/vulkancts/modules/vulkan/vktSynchronization.cpp \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderPackingFunctionTests.cpp \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderIntegerFunctionTests.cpp \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp \
index 834a20d..1d20ed4 100644 (file)
                                </TestCase>
                        </TestSuite>
                </TestSuite>
+               <TestCase name="synchronization">
+                       <Test name="fences">
+                               <TestInstance/>
+                       </Test>
+                       <Test name="semaphores">
+                               <TestInstance/>
+                       </Test>
+                       <Test name="events">
+                               <TestInstance/>
+                       </Test>
+               </TestCase>
        </TestSuite>
 </TestPackage>
index c711c8c..dddce41 100644 (file)
@@ -80294,3 +80294,6 @@ dEQP-VK.wsi.android.surface.query_capabilities
 dEQP-VK.wsi.android.surface.query_formats
 dEQP-VK.wsi.android.surface.query_present_modes
 dEQP-VK.wsi.android.surface.initial_size
+dEQP-VK.synchronization.fences
+dEQP-VK.synchronization.semaphores
+dEQP-VK.synchronization.events
index a575e8f..4829419 100644 (file)
@@ -49,6 +49,8 @@ set(DEQP_VK_COMMON_SRCS
        vktTestGroupUtil.hpp
        vktInfoTests.cpp
        vktInfoTests.hpp
+       vktSynchronization.cpp
+       vktSynchronization.hpp
        )
 
 set(DEQP_VK_COMMON_LIBS
diff --git a/external/vulkancts/modules/vulkan/vktSynchronization.cpp b/external/vulkancts/modules/vulkan/vktSynchronization.cpp
new file mode 100644 (file)
index 0000000..e6cdbc2
--- /dev/null
@@ -0,0 +1,1408 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Platform Synchronization tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSynchronization.hpp"
+
+#include "vktTestCaseUtil.hpp"
+
+#include "vkPlatform.hpp"
+#include "vkStrUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkDeviceUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuFormatUtil.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deThread.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+
+namespace vkt
+{
+
+using namespace vk;
+using namespace tcu;
+
+namespace
+{
+
+using std::vector;
+using std::string;
+using tcu::TestLog;
+using de::UniquePtr;
+using de::MovePtr;
+
+static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
+
+void buildShaders (SourceCollections& shaderCollection)
+{
+       shaderCollection.glslSources.add("glslvert") <<
+               glu::VertexSource(
+                               "#version 310 es\n"
+                               "precision mediump float;\n"
+                               "layout (location = 0) in vec4 vertexPosition;\n"
+                               "void main()\n"
+                               "{\n"
+                               "       gl_Position = vertexPosition;\n"
+                               "}\n");
+
+       shaderCollection.glslSources.add("glslfrag") <<
+               glu::FragmentSource(
+                               "#version 310 es\n"
+                               "precision mediump float;\n"
+                               "layout (location = 0) out vec4 outputColor;\n"
+                               "void main()\n"
+                               "{\n"
+                               "       outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
+                               "}\n");
+}
+
+Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
+{
+       VkDeviceQueueCreateInfo         queueInfo;
+       VkDeviceCreateInfo                      deviceInfo;
+       size_t                                          queueNdx;
+       const float                                     queuePriority   = 1.0f;
+
+       const vector<VkQueueFamilyProperties>   queueProps                              = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
+       const VkPhysicalDeviceFeatures                  physicalDeviceFeatures  = getPhysicalDeviceFeatures(vki, physicalDevice);
+
+       for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
+       {
+               if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
+                       break;
+       }
+
+       deMemset(&queueInfo,    0, sizeof(queueInfo));
+       deMemset(&deviceInfo,   0, sizeof(deviceInfo));
+
+       queueInfo.sType                                                 = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       queueInfo.pNext                                                 = DE_NULL;
+       queueInfo.flags                                                 = (VkDeviceQueueCreateFlags)0u;
+       queueInfo.queueFamilyIndex                              = (deUint32)queueNdx;
+       queueInfo.queueCount                                    = 2u;
+       queueInfo.pQueuePriorities                              = &queuePriority;
+
+       deviceInfo.sType                                                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+       deviceInfo.pNext                                                = DE_NULL;
+       deviceInfo.queueCreateInfoCount                 = 1u;
+       deviceInfo.pQueueCreateInfos                    = &queueInfo;
+       deviceInfo.enabledExtensionCount                = 0u;
+       deviceInfo.ppEnabledExtensionNames              = DE_NULL;
+       deviceInfo.enabledLayerCount                    = 0u;
+       deviceInfo.ppEnabledLayerNames                  = DE_NULL;
+       deviceInfo.pEnabledFeatures                             = &physicalDeviceFeatures;
+
+       return createDevice(vki, physicalDevice, &deviceInfo);
+};
+
+struct BufferParameters
+{
+       Context*                                                context;
+       VkDevice                                                device;
+       const void*                                             memory;
+       VkDeviceSize                                    size;
+       VkBufferUsageFlags                              usage;
+       VkSharingMode                                   sharingMode;
+       deUint32                                                queueFamilyCount;
+       const deUint32*                                 queueFamilyIndex;
+       VkAccessFlags                                   inputBarrierFlags;
+};
+
+struct Buffer
+{
+       MovePtr<Allocation>                             allocation;
+       vector<VkMemoryBarrier>                 memoryBarrier;
+       vk::Move<VkBuffer>                              buffer;
+};
+
+void createVulkanBuffer (const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
+{
+       TestLog&                                                        log                                     = bufferParameters.context->getTestContext().getLog();
+       const VkDevice                                          device                          = bufferParameters.device;
+       const VkPhysicalDevice                          physDevice                      = bufferParameters.context->getPhysicalDevice();
+       const DeviceInterface&                          deviceInterface         = bufferParameters.context->getDeviceInterface();
+       const InstanceInterface&                        instanceInterface       = bufferParameters.context->getInstanceInterface();
+       VkResult                                                        vkApiStatus;
+       VkPhysicalDeviceMemoryProperties        memProps;
+       VkMemoryRequirements                            memReq;
+       VkBufferCreateInfo                                      bufferCreateParams;
+       VkBuffer                                                        newBuffer;
+
+       bufferCreateParams.sType                                        = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+       bufferCreateParams.pNext                                        = DE_NULL;
+       bufferCreateParams.flags                                        = 0;
+       bufferCreateParams.size                                         = bufferParameters.size;
+       bufferCreateParams.usage                                        = bufferParameters.usage;
+       bufferCreateParams.sharingMode                          = bufferParameters.sharingMode;
+       bufferCreateParams.queueFamilyIndexCount        = bufferParameters.queueFamilyCount;
+       bufferCreateParams.pQueueFamilyIndices          = bufferParameters.queueFamilyIndex;
+
+       vkApiStatus = deviceInterface.createBuffer(device, &bufferCreateParams, DE_NULL, &newBuffer);
+       if (vkApiStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "Vulkan createBuffer  with (size,usage,sharingMode) = ("
+                       << bufferParameters.size << "," << bufferParameters.usage << "," << bufferParameters.sharingMode <<") failed with status "
+                       << vkApiStatus << TestLog::EndMessage;
+               VK_CHECK(vkApiStatus);
+       }
+
+       buffer.buffer = vk::Move<VkBuffer>(vk::check<VkBuffer>(newBuffer), Deleter<VkBuffer>(deviceInterface, device, DE_NULL));
+
+       instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
+       deviceInterface.getBufferMemoryRequirements(device, buffer.buffer.get(), &memReq);
+
+       {
+               Allocator&              allocator = bufferParameters.context->getDefaultAllocator();
+               MovePtr<Allocation>             newMemory       (allocator.allocate(memReq, visibility));
+
+               vkApiStatus = deviceInterface.bindBufferMemory(device, buffer.buffer.get(), newMemory->getMemory(), newMemory->getOffset());
+               if (vkApiStatus != VK_SUCCESS)
+               {
+                       log << TestLog::Message << "bindBufferMemory on device " << device
+                               << "failed with status " << vkApiStatus << TestLog::EndMessage;
+                       VK_CHECK(vkApiStatus);
+               }
+
+               // If caller provides a host memory buffer for the allocation, then go
+               // ahead and copy the provided data into the allocation and update the
+               // barrier list with the associated access
+               if (bufferParameters.memory != DE_NULL)
+               {
+                       VkMemoryBarrier                         barrier;
+                       VkMappedMemoryRange                     range;
+
+                       range.sType             = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+                       range.pNext             = DE_NULL;
+                       range.memory    = newMemory->getMemory();
+                       range.offset    = newMemory->getOffset();
+                       range.size              = bufferParameters.size;
+
+                       deMemcpy(newMemory->getHostPtr(), bufferParameters.memory, bufferParameters.size);
+                       VK_CHECK(deviceInterface.flushMappedMemoryRanges(device, 1, &range));
+
+                       barrier.sType                   = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+                       barrier.pNext                   = DE_NULL;
+                       barrier.srcAccessMask   = VK_ACCESS_HOST_WRITE_BIT;
+                       barrier.dstAccessMask   = bufferParameters.inputBarrierFlags;
+
+                       buffer.memoryBarrier.push_back(barrier);
+               }
+               buffer.allocation = newMemory;
+       }
+}
+
+struct ImageParameters
+{
+       Context*                                                        context;
+       VkDevice                                                        device;
+       VkImageType                                                     imageType;
+       VkFormat                                                        format;
+       VkExtent3D                                                      extent3D;
+       deUint32                                                        mipLevels;
+       VkSampleCountFlagBits                           samples;
+       VkImageTiling                                           tiling;
+       VkBufferUsageFlags                                      usage;
+       VkSharingMode                                           sharingMode;
+       deUint32                                                        queueFamilyCount;
+       const deUint32*                                         queueFamilyNdxList;
+       VkImageLayout                                           initialLayout;
+       VkImageLayout                                           finalLayout;
+       VkAccessFlags                                           barrierInputMask;
+};
+
+struct Image
+{
+       vk::Move<VkImage>                                       image;
+       vk::Move<VkImageView>                           imageView;
+       MovePtr<Allocation>                                     allocation;
+       vector<VkImageMemoryBarrier>            imageMemoryBarrier;
+};
+
+void createVulkanImage (const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
+{
+       TestLog&                                                        log                                     = imageParameters.context->getTestContext().getLog();
+       const DeviceInterface&                          deviceInterface         = imageParameters.context->getDeviceInterface();
+       const InstanceInterface&                        instanceInterface       = imageParameters.context->getInstanceInterface();
+       const VkPhysicalDevice                          physDevice                      = imageParameters.context->getPhysicalDevice();
+       const VkDevice                                          device                          = imageParameters.device;
+       VkResult                                                        result;
+       VkPhysicalDeviceMemoryProperties        memProps;
+       VkMemoryRequirements                            memReq;
+       VkComponentMapping                                      componentMap;
+       VkImageSubresourceRange                         subresourceRange;
+       VkImageViewCreateInfo                           imageViewCreateInfo;
+       VkImageCreateInfo                                       imageCreateParams;
+       VkImageMemoryBarrier                            imageBarrier;
+       VkImage                                                         newImage;
+       VkImageView                                                     newImageView;
+
+       imageCreateParams.sType                                 = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+       imageCreateParams.pNext                                 = DE_NULL;
+       imageCreateParams.flags                                 = 0;
+       imageCreateParams.imageType                             = imageParameters.imageType;
+       imageCreateParams.format                                = imageParameters.format;
+       imageCreateParams.extent                                = imageParameters.extent3D;
+       imageCreateParams.mipLevels                             = imageParameters.mipLevels;
+       imageCreateParams.arrayLayers                   = 1;
+       imageCreateParams.samples                               = imageParameters.samples;
+       imageCreateParams.tiling                                = imageParameters.tiling;
+       imageCreateParams.usage                                 = imageParameters.usage;
+       imageCreateParams.sharingMode                   = imageParameters.sharingMode;
+       imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
+       imageCreateParams.pQueueFamilyIndices   = imageParameters.queueFamilyNdxList;
+       imageCreateParams.initialLayout                 = imageParameters.initialLayout;
+
+       result = deviceInterface.createImage(device, &imageCreateParams, DE_NULL, &newImage);
+       if (result != VK_SUCCESS)
+       {
+               log << TestLog::Message << "createImage failed with status " << result << TestLog::EndMessage;
+               VK_CHECK(result);
+       }
+
+       image.image = vk::Move<VkImage>(vk::check<VkImage>(newImage), Deleter<VkImage>(deviceInterface, device, DE_NULL));
+
+       instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
+       deviceInterface.getImageMemoryRequirements(device, image.image.get(), &memReq);
+
+       {
+               Allocator&                              allocator = imageParameters.context->getDefaultAllocator();
+               MovePtr<Allocation>             newMemory       (allocator.allocate(memReq, visibility));
+               result = deviceInterface.bindImageMemory(device, image.image.get(), newMemory->getMemory(), newMemory->getOffset());
+               if (result != VK_SUCCESS)
+               {
+                       log << TestLog::Message << "bindImageMemory failed with status " << result << TestLog::EndMessage;
+                       VK_CHECK(result);
+               }
+
+               componentMap.r                                                  = VK_COMPONENT_SWIZZLE_R;
+               componentMap.g                                                  = VK_COMPONENT_SWIZZLE_G;
+               componentMap.b                                                  = VK_COMPONENT_SWIZZLE_B;
+               componentMap.a                                                  = VK_COMPONENT_SWIZZLE_A;
+
+               subresourceRange.aspectMask                             = VK_IMAGE_ASPECT_COLOR_BIT;
+               subresourceRange.baseMipLevel                   = 0;
+               subresourceRange.levelCount                             = imageParameters.mipLevels;
+               subresourceRange.baseArrayLayer                 = 0;
+               subresourceRange.layerCount                             = 1;
+
+               imageViewCreateInfo.sType                               = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+               imageViewCreateInfo.pNext                               = DE_NULL;
+               imageViewCreateInfo.flags                               = 0;
+               imageViewCreateInfo.image                               = image.image.get();
+               imageViewCreateInfo.viewType                    = VK_IMAGE_VIEW_TYPE_3D;
+               imageViewCreateInfo.format                              = imageParameters.format;
+               imageViewCreateInfo.components                  = componentMap;
+               imageViewCreateInfo.subresourceRange    = subresourceRange;
+
+               result = deviceInterface.createImageView(device, &imageViewCreateInfo, DE_NULL, &newImageView);
+               if (result != VK_SUCCESS)
+               {
+                       log << TestLog::Message << "createImageView failed with status " << result << TestLog::EndMessage;
+                       VK_CHECK(result);
+               }
+
+               image.imageView = vk::Move<VkImageView>(vk::check<VkImageView>(newImageView), Deleter<VkImageView>(deviceInterface, device, DE_NULL));
+               image.allocation = newMemory;
+
+               imageBarrier.sType                                      = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+               imageBarrier.pNext                                      = DE_NULL;
+               imageBarrier.srcAccessMask                      = 0;
+               imageBarrier.dstAccessMask                      = imageParameters.barrierInputMask;
+               imageBarrier.oldLayout                          = imageParameters.initialLayout;
+               imageBarrier.newLayout                          = imageParameters.finalLayout;
+               imageBarrier.srcQueueFamilyIndex        = imageParameters.queueFamilyNdxList[0];
+               imageBarrier.dstQueueFamilyIndex        = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
+               imageBarrier.image                                      = image.image.get();
+               imageBarrier.subresourceRange           = subresourceRange;
+
+               image.imageMemoryBarrier.push_back(imageBarrier);
+       }
+}
+
+struct RenderPassParameters
+{
+       Context*                                context;
+       VkDevice                                device;
+       VkFormat                                colorFormat;
+       VkSampleCountFlagBits   colorSamples;
+};
+
+void  createColorOnlyRenderPass (const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
+{
+       const DeviceInterface&                          deviceInterface         = renderPassParameters.context->getDeviceInterface();
+       const VkDevice                                          device                          = renderPassParameters.device;
+       VkAttachmentDescription                         colorAttachmentDesc;
+       VkAttachmentReference                           colorAttachmentRef;
+       VkAttachmentReference                           stencilAttachmentRef;
+       VkSubpassDescription                            subpassDesc;
+       VkRenderPassCreateInfo                          renderPassParams;
+       VkRenderPass                                            newRenderPass;
+
+       colorAttachmentDesc.flags                       = 0;
+       colorAttachmentDesc.format                      = renderPassParameters.colorFormat;
+       colorAttachmentDesc.samples                     = renderPassParameters.colorSamples;
+       colorAttachmentDesc.loadOp                      = VK_ATTACHMENT_LOAD_OP_CLEAR;
+       colorAttachmentDesc.storeOp                     = VK_ATTACHMENT_STORE_OP_STORE;
+       colorAttachmentDesc.stencilLoadOp       = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+       colorAttachmentDesc.stencilStoreOp      = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+       colorAttachmentDesc.initialLayout       = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+       colorAttachmentDesc.finalLayout         = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+       colorAttachmentRef.attachment           = 0;
+       colorAttachmentRef.layout                       = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+       stencilAttachmentRef.attachment         = VK_NO_ATTACHMENT;
+       stencilAttachmentRef.layout                     = VK_IMAGE_LAYOUT_UNDEFINED;
+
+       subpassDesc.flags                                       = 0;
+       subpassDesc.pipelineBindPoint           = VK_PIPELINE_BIND_POINT_GRAPHICS;
+       subpassDesc.inputAttachmentCount        = 0;
+       subpassDesc.pInputAttachments           = DE_NULL;
+       subpassDesc.colorAttachmentCount        = 1;
+       subpassDesc.pColorAttachments           = &colorAttachmentRef;
+       subpassDesc.pResolveAttachments         = DE_NULL;
+       subpassDesc.pDepthStencilAttachment     = &stencilAttachmentRef;
+       subpassDesc.preserveAttachmentCount     = 0;
+       subpassDesc.pPreserveAttachments        = DE_NULL;
+
+       renderPassParams.sType                          = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+       renderPassParams.pNext                          = DE_NULL;
+       renderPassParams.flags                          = 0;
+       renderPassParams.attachmentCount        = 1;
+       renderPassParams.pAttachments           = &colorAttachmentDesc;
+       renderPassParams.subpassCount           = 1;
+       renderPassParams.pSubpasses                     = &subpassDesc;
+       renderPassParams.dependencyCount        = 0;
+       renderPassParams.pDependencies          = DE_NULL;
+
+       VK_CHECK(deviceInterface.createRenderPass(device, &renderPassParams, DE_NULL, &newRenderPass));
+       renderPass = vk::Move<VkRenderPass>(vk::check<VkRenderPass>(newRenderPass), Deleter<VkRenderPass>(deviceInterface, device, DE_NULL));
+}
+
+struct ShaderDescParams
+{
+       const char*                             name;
+       VkShaderStageFlagBits   stage;
+};
+
+void createGraphicsShaderStages (Context& context, const VkDevice device, vector<ShaderDescParams> shaderDesc, vector<VkPipelineShaderStageCreateInfo>& shaderCreateParams)
+{
+       const DeviceInterface&                          deviceInterface         = context.getDeviceInterface();
+
+       for (vector<ShaderDescParams>::iterator shaderDescIter = shaderDesc.begin(); shaderDescIter != shaderDesc.end(); shaderDescIter++)
+       {
+               VkPipelineShaderStageCreateInfo         shaderStageInfo;
+               VkShaderModule                                          shaderModule;
+               VkShaderModuleCreateInfo                        shaderModuleInfo;
+
+               shaderModuleInfo.sType                          = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+               shaderModuleInfo.pNext                          = DE_NULL;
+               shaderModuleInfo.flags                          = 0;
+               shaderModuleInfo.codeSize                       = context.getBinaryCollection().get(shaderDescIter->name).getSize();
+               shaderModuleInfo.pCode                          = (const deUint32*)context.getBinaryCollection().get(shaderDescIter->name).getBinary();
+               VK_CHECK(deviceInterface.createShaderModule(device, &shaderModuleInfo, DE_NULL, &shaderModule));
+
+               shaderStageInfo.sType                           = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+               shaderStageInfo.pNext                           = DE_NULL;
+               shaderStageInfo.flags                           = 0;
+               shaderStageInfo.stage                           = shaderDescIter->stage;
+               shaderStageInfo.module                          = shaderModule;
+               shaderStageInfo.pName                           = "main";
+               shaderStageInfo.pSpecializationInfo     = DE_NULL;
+               shaderCreateParams.push_back(shaderStageInfo);
+       }
+}
+
+struct VertexDesc
+{
+       deUint32        location;
+       VkFormat        format;
+       deUint32        stride;
+       deUint32        offset;
+};
+
+void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
+{
+       for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
+       {
+               deUint32                                                        bindingId = 0;
+               VkVertexInputBindingDescription         bindingDesc;
+               VkVertexInputAttributeDescription       attrDesc;
+
+               bindingDesc.binding             = bindingId;
+               bindingDesc.stride              = vertDescIter->stride;
+               bindingDesc.inputRate   = VK_VERTEX_INPUT_RATE_VERTEX;
+               bindingList.push_back(bindingDesc);
+
+               attrDesc.location               = vertDescIter->location;
+               attrDesc.binding                = bindingId;
+               attrDesc.format                 = vertDescIter->format;
+               attrDesc.offset                 = vertDescIter->offset;
+               attrList.push_back(attrDesc);
+
+               bindingId++;
+       }
+
+       vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+       vertexInputState.pNext = DE_NULL,
+       vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
+       vertexInputState.pVertexBindingDescriptions = &bindingList[0];
+       vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
+       vertexInputState.pVertexAttributeDescriptions = &attrList[0];
+}
+
+void createCommandBuffer (Context& context, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef)
+{
+       const DeviceInterface&          deviceInterface         = context.getDeviceInterface();
+       VkCommandPool                           commandPool;
+       VkCommandPoolCreateInfo         commandPoolInfo;
+       VkCommandBufferAllocateInfo     commandBufferInfo;
+       VkCommandBuffer                         commandBuffer;
+
+       commandPoolInfo.sType                           = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+       commandPoolInfo.pNext                           = DE_NULL;
+       commandPoolInfo.flags                           = 0;
+       commandPoolInfo.queueFamilyIndex        = queueFamilyNdx;
+
+       VK_CHECK(deviceInterface.createCommandPool(device, &commandPoolInfo, DE_NULL, &commandPool));
+
+       commandBufferInfo.sType                                 = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+       commandBufferInfo.pNext                                 = DE_NULL;
+       commandBufferInfo.commandPool                   = commandPool;
+       commandBufferInfo.level                                 = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+       commandBufferInfo.commandBufferCount    = 1;
+
+       VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
+       *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, DE_NULL));
+}
+
+void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
+{
+       VkFenceCreateInfo               fenceState;
+       VkFenceCreateFlags              signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
+
+       fenceState.sType                = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+       fenceState.pNext                = DE_NULL;
+       fenceState.flags                = signalFlag;
+
+       for (deUint32 ndx = 0; ndx < numFences; ndx++)
+               VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
+}
+
+void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
+{
+       for (deUint32 ndx = 0; ndx < numFences; ndx++)
+               deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
+}
+
+struct RenderInfo
+{
+       Context*                                                context;
+       deInt32                                                 width;
+       deInt32                                                 height;
+       deUint32                                                vertexBufferSize;
+       VkBuffer                                                vertexBuffer;
+       VkImage                                                 image;
+       VkCommandBuffer                                 commandBuffer;
+       VkRenderPass                                    renderPass;
+       VkFramebuffer                                   framebuffer;
+       VkPipeline                                              pipeline;
+       deUint32                                                mipLevels;
+       const deUint32*                                 queueFamilyNdxList;
+       deUint32                                                queueFamilyNdxCount;
+       bool                                                    setEvent;
+       bool                                                    waitEvent;
+       VkEvent                                                 event;
+       vector<VkImageMemoryBarrier>*   barriers;
+};
+
+void  recordRenderPass (const RenderInfo& renderInfo)
+{
+       const DeviceInterface&                          deviceInterface                 = renderInfo.context->getDeviceInterface();
+       const VkDeviceSize                                      bindingOffset                   = 0;
+       const VkClearValue                                      clearValue                              = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
+       VkRenderPassBeginInfo                           renderPassBeginState;
+       VkImageMemoryBarrier                            renderBarrier;
+
+       renderPassBeginState.sType                                              = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+       renderPassBeginState.pNext                                              = DE_NULL;
+       renderPassBeginState.renderPass                                 = renderInfo.renderPass;
+       renderPassBeginState.framebuffer                                = renderInfo.framebuffer;
+       renderPassBeginState.renderArea.offset.x                = 0;
+       renderPassBeginState.renderArea.offset.y                = 0;
+       renderPassBeginState.renderArea.extent.width    = renderInfo.width;
+       renderPassBeginState.renderArea.extent.height   = renderInfo.height;
+       renderPassBeginState.clearValueCount                    = 1;
+       renderPassBeginState.pClearValues                               = &clearValue;
+
+       deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
+       if (renderInfo.waitEvent)
+               deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
+       deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
+       deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
+       deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
+       if (renderInfo.setEvent)
+               deviceInterface.cmdSetEvent(renderInfo.commandBuffer, renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
+       deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
+
+       renderBarrier.sType                                                             = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+       renderBarrier.pNext                                                             = DE_NULL;
+       renderBarrier.srcAccessMask                                             = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+       renderBarrier.dstAccessMask                                             = VK_ACCESS_TRANSFER_READ_BIT;
+       renderBarrier.oldLayout                                                 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+       renderBarrier.newLayout                                                 = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       renderBarrier.srcQueueFamilyIndex                               = renderInfo.queueFamilyNdxList[0];
+       renderBarrier.dstQueueFamilyIndex                               = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
+       renderBarrier.image                                                             = renderInfo.image;
+       renderBarrier.subresourceRange.aspectMask               = VK_IMAGE_ASPECT_COLOR_BIT;
+       renderBarrier.subresourceRange.baseMipLevel             = 0;
+       renderBarrier.subresourceRange.levelCount               = renderInfo.mipLevels;
+       renderBarrier.subresourceRange.baseArrayLayer   = 0;
+       renderBarrier.subresourceRange.layerCount               = 1;
+       renderInfo.barriers->push_back(renderBarrier);
+}
+
+struct TransferInfo
+{
+       Context*                                                context;
+       VkCommandBuffer                                 commandBuffer;
+       deUint32                                                width;
+       deUint32                                                height;
+       VkImage                                                 image;
+       VkBuffer                                                buffer;
+       VkDeviceSize                                    size;
+       deUint32                                                mipLevel;
+       VkOffset3D                                              imageOffset;
+       vector<VkBufferMemoryBarrier>*  barriers;
+};
+
+void copyToCPU (TransferInfo* transferInfo)
+{
+       const DeviceInterface&                          deviceInterface                 = transferInfo->context->getDeviceInterface();
+       VkBufferImageCopy                                       copyState;
+
+       copyState.bufferOffset                                          = 0;
+       copyState.bufferRowLength                                       = transferInfo->width;
+       copyState.bufferImageHeight                                     = transferInfo->height;
+       copyState.imageSubresource.aspectMask           = VK_IMAGE_ASPECT_COLOR_BIT;
+       copyState.imageSubresource.mipLevel                     = transferInfo->mipLevel;
+       copyState.imageSubresource.baseArrayLayer       = 0;
+       copyState.imageSubresource.layerCount           = 1;
+       copyState.imageOffset                                           = transferInfo->imageOffset;
+       copyState.imageExtent.width                                     = (deInt32)(transferInfo->width);
+       copyState.imageExtent.height                            = (deInt32)(transferInfo->height);
+       copyState.imageExtent.depth                                     = 1;
+
+       deviceInterface.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, &copyState);
+
+       {
+               VkBufferMemoryBarrier   bufferBarrier;
+               bufferBarrier.sType                                     = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+               bufferBarrier.pNext                                     = DE_NULL;
+               bufferBarrier.srcAccessMask                     = VK_ACCESS_TRANSFER_WRITE_BIT;
+               bufferBarrier.dstAccessMask                     = VK_ACCESS_HOST_READ_BIT;
+               bufferBarrier.srcQueueFamilyIndex       = VK_QUEUE_FAMILY_IGNORED;
+               bufferBarrier.dstQueueFamilyIndex       = VK_QUEUE_FAMILY_IGNORED;
+               bufferBarrier.buffer                            = transferInfo->buffer;
+               bufferBarrier.offset                            = 0;
+               bufferBarrier.size                                      = transferInfo->size;
+               transferInfo->barriers->push_back(bufferBarrier);
+       }
+}
+
+struct TestContext
+{
+       Context&                                        context;
+       const VkDevice&                         device;
+       const tcu::Vec4*                        vertices;
+       deUint32                                        numVertices;
+       tcu::IVec2                                      renderDimension;
+       VkFence                                         fences[2];
+       VkDeviceSize                            renderSize;
+       MovePtr<Allocation>                     renderReadBuffer;
+       MovePtr<Allocation>                     vertexBufferAllocation;
+       vk::Move<VkBuffer>                      vertexBuffer;
+       vk::Move<VkBuffer>                      renderBuffer;
+       bool                                            setEvent;
+       bool                                            waitEvent;
+       VkEvent                                         event;
+       vk::Move<VkImage>                       image;
+       vk::Move<VkImageView>           imageView;
+       vk::Move<VkCommandBuffer>       cmdBuffer;
+       MovePtr<Allocation>                     imageAllocation;
+
+       TestContext(Context& context_, const VkDevice& device_)
+               : context               (context_)
+               , device                (device_)
+               , numVertices   (0)
+               , setEvent              (DE_FALSE)
+               , waitEvent             (DE_FALSE)
+       {
+               createFences(context.getDeviceInterface(), device, DE_NULL, DE_LENGTH_OF_ARRAY(fences), fences);
+       }
+
+       ~TestContext()
+       {
+               destroyFences(context.getDeviceInterface(), device, DE_LENGTH_OF_ARRAY(fences), fences);
+       }
+};
+
+void generateWork (TestContext& testContext)
+{
+       const DeviceInterface&                                          deviceInterface         = testContext.context.getDeviceInterface();
+       const deUint32                                                          queueFamilyNdx          = testContext.context.getUniversalQueueFamilyIndex();
+       vk::Move<VkRenderPass>                                          renderPass;
+       VkPipelineCache                                                         cache;
+       VkPipelineLayout                                                        layout;
+       VkPipeline                                                                      pipeline;
+       VkFramebuffer                                                           framebuffer;
+       vector<ShaderDescParams>                                        shaderDescParams;
+       vector<VkPipelineShaderStageCreateInfo>         shaderStageCreateParams;
+       VertexDesc                                                                      vertexDesc;
+       vector<VertexDesc>                                                      vertexDescList;
+       vector<VkVertexInputAttributeDescription>       attrList;
+       vector<VkBufferMemoryBarrier>                           bufferMemoryBarrier;
+       deUint32                                                                        memoryBarrierNdx;
+       deUint32                                                                        bufferMemoryBarrierNdx;
+       deUint32                                                                        imageMemoryBarrierNdx;
+       vector<VkVertexInputBindingDescription>         bindingList;
+       VkPipelineVertexInputStateCreateInfo            vertexInputState;
+       VkPipelineInputAssemblyStateCreateInfo          inputAssemblyState;
+       VkPipelineDepthStencilStateCreateInfo           depthStencilState;
+       VkPipelineColorBlendAttachmentState                     blendAttachment;
+       VkPipelineColorBlendStateCreateInfo                     blendState;
+       VkPipelineDynamicStateCreateInfo                        dynamicState;
+       VkPipelineLayoutCreateInfo                                      pipelineLayoutState;
+       VkGraphicsPipelineCreateInfo                            pipelineState;
+       VkPipelineCacheCreateInfo                                       cacheState;
+       VkViewport                                                                      viewport;
+       VkPipelineViewportStateCreateInfo                       viewportInfo;
+       VkRect2D                                                                        scissor;
+       BufferParameters                                                        bufferParameters;
+       Buffer                                                                          buffer;
+       RenderInfo                                                                      renderInfo;
+       ImageParameters                                                         imageParameters;
+       Image                                                                           image;
+       VkPipelineRasterizationStateCreateInfo          rasterState;
+       VkPipelineMultisampleStateCreateInfo            multisampleState;
+       VkFramebufferCreateInfo                                         fbState;
+       VkCommandBufferBeginInfo                                        commandBufRecordState;
+       VkCommandBufferInheritanceInfo                          inheritanceInfo;
+       RenderPassParameters                                            renderPassParameters;
+       TransferInfo                                                            transferInfo;
+       vector<void*>                                                           barrierList;
+       VkExtent3D                                                                      extent;
+       vector<VkMemoryBarrier>                                         memoryBarriers;
+       vector<VkBufferMemoryBarrier>                           bufferBarriers;
+       vector<VkImageMemoryBarrier>                            imageBarriers;
+
+       memoryBarrierNdx                        = 0;
+       bufferMemoryBarrierNdx          = 0;
+       imageMemoryBarrierNdx           = 0;
+       buffer.memoryBarrier.resize(memoryBarrierNdx);
+       bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
+       image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
+
+       memoryBarriers.resize(0);
+       bufferBarriers.resize(0);
+       imageBarriers.resize(0);
+
+       bufferParameters.context                                = &testContext.context;
+       bufferParameters.device                                 = testContext.device;
+       bufferParameters.memory                                 = testContext.vertices;
+       bufferParameters.size                                   = testContext.numVertices * sizeof(tcu::Vec4);
+       bufferParameters.usage                                  = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+       bufferParameters.sharingMode                    = VK_SHARING_MODE_EXCLUSIVE;
+       bufferParameters.queueFamilyCount               = 1;
+       bufferParameters.queueFamilyIndex               = &queueFamilyNdx;
+       bufferParameters.inputBarrierFlags              = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+       createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
+       testContext.vertexBufferAllocation              = buffer.allocation;
+       testContext.vertexBuffer                                = buffer.buffer;
+
+       bufferParameters.context                                = &testContext.context;
+       bufferParameters.device                                 = testContext.device;
+       bufferParameters.memory                                 = DE_NULL;
+       bufferParameters.size                                   = testContext.renderSize;
+       bufferParameters.usage                                  = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+       bufferParameters.sharingMode                    = VK_SHARING_MODE_EXCLUSIVE;
+       bufferParameters.queueFamilyCount               = 1;
+       bufferParameters.queueFamilyIndex               = &queueFamilyNdx;
+       bufferParameters.inputBarrierFlags              = 0;
+       createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
+       testContext.renderReadBuffer                    = buffer.allocation;
+       testContext.renderBuffer                                = buffer.buffer;
+
+       extent.width                                                    = testContext.renderDimension.x();
+       extent.height                                                   = testContext.renderDimension.y();
+       extent.depth                                                    = 1;
+
+       imageParameters.context                                 = &testContext.context;
+       imageParameters.device                                  = testContext.device;
+       imageParameters.imageType                               = VK_IMAGE_TYPE_2D;
+       imageParameters.format                                  = VK_FORMAT_R8G8B8A8_UNORM;
+       imageParameters.extent3D                                = extent;
+       imageParameters.mipLevels                               = 1;
+       imageParameters.samples                                 = VK_SAMPLE_COUNT_1_BIT;
+       imageParameters.tiling                                  = VK_IMAGE_TILING_OPTIMAL;
+       imageParameters.usage                                   = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+       imageParameters.sharingMode                             = VK_SHARING_MODE_EXCLUSIVE;
+       imageParameters.queueFamilyCount                = 1;
+       imageParameters.queueFamilyNdxList              = &queueFamilyNdx;
+       imageParameters.initialLayout                   = VK_IMAGE_LAYOUT_UNDEFINED;
+       imageParameters.finalLayout                             = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+       imageParameters.barrierInputMask                = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+       createVulkanImage(imageParameters, image, MemoryRequirement::Any);
+       testContext.imageAllocation                             = image.allocation;
+       testContext.image                                               = image.image;
+
+       renderPassParameters.context                    = &testContext.context;
+       renderPassParameters.device                             = testContext.device;
+       renderPassParameters.colorFormat                = VK_FORMAT_R8G8B8A8_UNORM;
+       renderPassParameters.colorSamples               = VK_SAMPLE_COUNT_1_BIT;
+       createColorOnlyRenderPass(renderPassParameters, renderPass);
+
+       ShaderDescParams param;
+       param.name = "glslvert";
+       param.stage = VK_SHADER_STAGE_VERTEX_BIT;
+       shaderDescParams.push_back(param);
+
+       param.name = "glslfrag";
+       param.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+       shaderDescParams.push_back(param);
+       createGraphicsShaderStages(testContext.context, testContext.device, shaderDescParams, shaderStageCreateParams);
+
+       vertexDesc.location = 0;
+       vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
+       vertexDesc.stride = sizeof(tcu::Vec4);
+       vertexDesc.offset = 0;
+       vertexDescList.push_back(vertexDesc);
+
+       createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
+
+       inputAssemblyState.sType                                        = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+       inputAssemblyState.pNext                                        = DE_NULL;
+       inputAssemblyState.topology                                     = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+       inputAssemblyState.primitiveRestartEnable       = DE_FALSE;
+
+       viewport.x                                                                      = 0;
+       viewport.y                                                                      = 0;
+       viewport.width                                                          = (float)testContext.renderDimension.x();
+       viewport.height                                                         = (float)testContext.renderDimension.y();
+       viewport.minDepth                                                       = 0;
+       viewport.maxDepth                                                       = 1;
+
+       scissor.offset.x                                                        = 0;
+       scissor.offset.y                                                        = 0;
+       scissor.extent.width                                            = testContext.renderDimension.x();
+       scissor.extent.height                                           = testContext.renderDimension.y();
+
+       viewportInfo.sType                                                      = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+       viewportInfo.pNext                                                      = DE_NULL;
+       viewportInfo.flags                                                      = 0;
+       viewportInfo.viewportCount                                      = 1;
+       viewportInfo.pViewports                                         = &viewport;
+       viewportInfo.scissorCount                                       = 1;
+       viewportInfo.pScissors                                          = &scissor;
+
+       rasterState.sType                                                       = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+       rasterState.pNext                                                       = DE_NULL;
+       rasterState.flags                                                       = 0;
+       rasterState.depthClampEnable                            = VK_TRUE;
+       rasterState.rasterizerDiscardEnable                     = VK_FALSE;
+       rasterState.polygonMode                                         = VK_POLYGON_MODE_FILL;
+       rasterState.cullMode                                            = VK_CULL_MODE_NONE;
+       rasterState.frontFace                                           = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+       rasterState.depthBiasEnable                                     = VK_FALSE;
+       rasterState.lineWidth                                           = 1;
+
+       multisampleState.sType                                          = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+       multisampleState.pNext                                          = DE_NULL;
+       multisampleState.flags                                          = 0;
+       multisampleState.rasterizationSamples           = VK_SAMPLE_COUNT_1_BIT;
+       multisampleState.sampleShadingEnable            = VK_FALSE;
+       multisampleState.pSampleMask                            = DE_NULL;
+       multisampleState.alphaToCoverageEnable          = VK_FALSE;
+       multisampleState.alphaToOneEnable                       = VK_FALSE;
+
+       depthStencilState.sType                                         = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+       depthStencilState.pNext                                         = DE_NULL;
+       depthStencilState.flags                                         = 0;
+       depthStencilState.depthTestEnable                       = VK_FALSE;
+       depthStencilState.depthWriteEnable                      = VK_FALSE;
+       depthStencilState.depthBoundsTestEnable         = VK_FALSE;
+       depthStencilState.stencilTestEnable                     = VK_FALSE;
+
+       blendAttachment.blendEnable                                     = VK_FALSE;
+
+       blendState.sType                                                        = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+       blendState.pNext                                                        = DE_NULL;
+       blendState.flags                                                        = 0;
+       blendState.logicOpEnable                                        = VK_FALSE;
+       blendState.attachmentCount                                      = 1;
+       blendState.pAttachments                                         = &blendAttachment;
+
+       dynamicState.sType                                                      = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+       dynamicState.pNext                                                      = DE_NULL;
+       dynamicState.flags                                                      = 0;
+       dynamicState.dynamicStateCount                          = 0;
+       dynamicState.pDynamicStates                                     = DE_NULL;
+
+       pipelineLayoutState.sType                                       = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+       pipelineLayoutState.pNext                                       = DE_NULL;
+       pipelineLayoutState.flags                                       = 0;
+       pipelineLayoutState.setLayoutCount                      = 0;
+       pipelineLayoutState.pSetLayouts                         = DE_NULL;
+       pipelineLayoutState.pushConstantRangeCount      = 0;
+       pipelineLayoutState.pPushConstantRanges         = DE_NULL;
+       VK_CHECK(deviceInterface.createPipelineLayout(testContext.device, &pipelineLayoutState, DE_NULL, &layout));
+
+       pipelineState.sType                                                     = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+       pipelineState.pNext                                                     = DE_NULL;
+       pipelineState.flags                                                     = 0;
+       pipelineState.stageCount                                        = (deUint32)shaderStageCreateParams.size();
+       pipelineState.pStages                                           = &shaderStageCreateParams[0];
+       pipelineState.pVertexInputState                         = &vertexInputState;
+       pipelineState.pInputAssemblyState                       = &inputAssemblyState;
+       pipelineState.pTessellationState                        = DE_NULL;
+       pipelineState.pViewportState                            = &viewportInfo;
+       pipelineState.pRasterizationState                       = &rasterState;
+       pipelineState.pMultisampleState                         = &multisampleState;
+       pipelineState.pDepthStencilState                        = &depthStencilState;
+       pipelineState.pColorBlendState                          = &blendState;
+       pipelineState.pDynamicState                                     = &dynamicState;
+       pipelineState.layout                                            = layout;
+       pipelineState.renderPass                                        = renderPass.get();
+       pipelineState.subpass                                           = 0;
+       pipelineState.basePipelineHandle                        = DE_NULL;
+       pipelineState.basePipelineIndex                         = 0;
+
+       cacheState.sType                                                        = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+       cacheState.pNext                                                        = DE_NULL;
+       cacheState.flags                                                        = 0;
+       cacheState.initialDataSize                                      = 0;
+       cacheState.pInitialData                                         = DE_NULL;
+
+       VK_CHECK(deviceInterface.createPipelineCache(testContext.device, &cacheState, DE_NULL, &cache));
+       VK_CHECK(deviceInterface.createGraphicsPipelines(testContext.device, cache, 1, &pipelineState, DE_NULL, &pipeline));
+
+       fbState.sType                                                           = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+       fbState.pNext                                                           = DE_NULL;
+       fbState.flags                                                           = 0;
+       fbState.renderPass                                                      = renderPass.get();
+       fbState.attachmentCount                                         = 1;
+       fbState.pAttachments                                            = &image.imageView.get();
+       fbState.width                                                           = (deUint32)testContext.renderDimension.x();
+       fbState.height                                                          = (deUint32)testContext.renderDimension.y();
+       fbState.layers                                                          = 1;
+       VK_CHECK(deviceInterface.createFramebuffer(testContext.device, &fbState, DE_NULL, &framebuffer));
+       testContext.imageView                                           = image.imageView;
+
+       inheritanceInfo.sType                                           = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+       inheritanceInfo.pNext                                           = DE_NULL;
+       inheritanceInfo.renderPass                                      = renderPass.get();
+       inheritanceInfo.subpass                                         = 0;
+       inheritanceInfo.framebuffer                                     = framebuffer;
+       inheritanceInfo.occlusionQueryEnable            = VK_FALSE;
+
+       commandBufRecordState.sType                                     = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+       commandBufRecordState.pNext                                     = DE_NULL;
+       commandBufRecordState.flags                                     = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+       commandBufRecordState.pInheritanceInfo          = &inheritanceInfo;
+       VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
+
+       deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
+                                                                               VK_PIPELINE_STAGE_HOST_BIT,
+                                                                               VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                                                               DE_FALSE,
+                                                                               (deUint32)memoryBarriers.size(), &memoryBarriers[0],
+                                                                               (deUint32)bufferBarriers.size(), &bufferBarriers[0],
+                                                                               (deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+       memoryBarriers.resize(0);
+       bufferBarriers.resize(0);
+       imageBarriers.resize(0);
+
+       renderInfo.context                              = &testContext.context;
+       renderInfo.width                                = testContext.renderDimension.x();
+       renderInfo.height                               = testContext.renderDimension.y();
+       renderInfo.vertexBufferSize             = testContext.numVertices;
+       renderInfo.vertexBuffer                 = testContext.vertexBuffer.get();
+       renderInfo.image                                = testContext.image.get();
+       renderInfo.commandBuffer                = testContext.cmdBuffer.get();
+       renderInfo.renderPass                   = renderPass.get();
+       renderInfo.framebuffer                  = framebuffer;
+       renderInfo.pipeline                             = pipeline;
+       renderInfo.mipLevels                    = 1;
+       renderInfo.queueFamilyNdxList   = &queueFamilyNdx;
+       renderInfo.queueFamilyNdxCount  = 1;
+       renderInfo.setEvent                             = testContext.setEvent;
+       renderInfo.waitEvent                    = testContext.waitEvent;
+       renderInfo.event                                = testContext.event;
+       renderInfo.barriers                             = &imageBarriers;
+       recordRenderPass(renderInfo);
+
+       deviceInterface.cmdPipelineBarrier(     renderInfo.commandBuffer,
+                                                                               VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+                                                                               VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                                                               DE_FALSE,
+                                                                               (deUint32)memoryBarriers.size(), &memoryBarriers[0],
+                                                                               (deUint32)bufferBarriers.size(), &bufferBarriers[0],
+                                                                               (deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+       memoryBarriers.resize(0);
+       bufferBarriers.resize(0);
+       imageBarriers.resize(0);
+
+       transferInfo.context = &testContext.context;
+       transferInfo.commandBuffer              = renderInfo.commandBuffer;
+       transferInfo.width                              = testContext.renderDimension.x();
+       transferInfo.height                             = testContext.renderDimension.y();
+       transferInfo.image                              = renderInfo.image;
+       transferInfo.buffer                             = testContext.renderBuffer.get();
+       transferInfo.size                               = testContext.renderSize;
+       transferInfo.mipLevel                   = 0;
+       transferInfo.imageOffset.x              = 0;
+       transferInfo.imageOffset.y              = 0;
+       transferInfo.imageOffset.z              = 0;
+       transferInfo.barriers                   = &bufferBarriers;
+       copyToCPU(&transferInfo);
+
+       deviceInterface.cmdPipelineBarrier(     transferInfo.commandBuffer,
+                                                                               VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                                                               VK_PIPELINE_STAGE_HOST_BIT,
+                                                                               DE_FALSE,
+                                                                               (deUint32)memoryBarriers.size(), &memoryBarriers[0],
+                                                                               (deUint32)bufferBarriers.size(), &bufferBarriers[0],
+                                                                               (deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+       memoryBarriers.resize(0);
+       bufferBarriers.resize(0);
+       imageBarriers.resize(0);
+
+       VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
+}
+
+static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
+{
+       for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
+       {
+               submitInfo[ndx].sType                                   = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+               submitInfo[ndx].pNext                                   = DE_NULL;
+               submitInfo[ndx].waitSemaphoreCount              = 0;
+               submitInfo[ndx].pWaitSemaphores                 = DE_NULL;
+               submitInfo[ndx].pWaitDstStageMask               = DE_NULL;
+               submitInfo[ndx].commandBufferCount              = 1;
+               submitInfo[ndx].signalSemaphoreCount    = 0;
+               submitInfo[ndx].pSignalSemaphores               = DE_NULL;
+       }
+}
+
+tcu::TestStatus testFences (Context& context)
+{
+       TestLog&                                        log                                     = context.getTestContext().getLog();
+       const DeviceInterface&          deviceInterface         = context.getDeviceInterface();
+       const InstanceInterface&        instanceInterface       = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice          = context.getPhysicalDevice();
+       const VkQueue                           queue                           = context.getUniversalQueue();
+       const deUint32                          queueFamilyIdx          = context.getUniversalQueueFamilyIndex();
+       vk::Move<VkDevice>                      device                          = createTestDevice(instanceInterface, physicalDevice);
+       VkResult                                        testStatus;
+       VkResult                                        fenceStatus;
+       TestContext                                     testContext(context, device.get());
+       VkSubmitInfo                            submitInfo;
+       VkMappedMemoryRange                     range;
+       void*                                           resultImage;
+
+       const tcu::Vec4                         vertices[]                      =
+       {
+               tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+       };
+
+       testContext.vertices = vertices;
+       testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
+       testContext.renderDimension = tcu::IVec2(256, 256);
+       testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
+
+       createCommandBuffer(testContext.context, device.get(), queueFamilyIdx, &testContext.cmdBuffer);
+       generateWork(testContext);
+
+       initSubmitInfo(&submitInfo, 1);
+       submitInfo.pCommandBuffers              = &testContext.cmdBuffer.get();
+
+       VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
+
+       fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
+       if (fenceStatus != VK_NOT_READY)
+       {
+               log << TestLog::Message << "testSynchronizationPrimitives fence should be reset but status is " << fenceStatus << TestLog::EndMessage;
+               return tcu::TestStatus::fail("Fence in incorrect state");
+       }
+
+       testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_TIMEOUT)
+       {
+               log << TestLog::Message << "testSynchPrimitives failed to wait for all fences" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("Failed to wait for mulitple fences");
+       }
+
+       testStatus = deviceInterface.waitForFences(device.get(),
+                                                                                               1,
+                                                                                               &testContext.fences[1],
+                                                                                               DE_TRUE,
+                                                                                               DEFAULT_TIMEOUT);
+
+       if (testStatus != VK_TIMEOUT)
+       {
+               log << TestLog::Message << "testSyncPrimitives failed to wait for single fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for single fence");
+       }
+
+       testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for a set fence");
+       }
+
+       fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
+       if (fenceStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << fenceStatus << TestLog::EndMessage;
+               return tcu::TestStatus::fail("Fence in incorrect state");
+       }
+
+       range.sType                     = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+       range.pNext                     = DE_NULL;
+       range.memory            = testContext.renderReadBuffer->getMemory();
+       range.offset            = 0;
+       range.size                      = testContext.renderSize;
+       VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+       resultImage = testContext.renderReadBuffer->getHostPtr();
+
+       log << TestLog::Image(  "result",
+                                                       "result",
+                                                       tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                       tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+                                                                       testContext.renderDimension.x(),
+                                                                       testContext.renderDimension.y(),
+                                                                       1,
+                                                                       resultImage));
+
+       return TestStatus::pass("synchornization-fences passed");
+}
+
+vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
+{
+       VkSemaphoreCreateInfo           semaCreateInfo;
+       VkSemaphore                                     semaphore;
+
+       semaCreateInfo.sType            = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+       semaCreateInfo.pNext            = DE_NULL;
+       semaCreateInfo.flags            = 0;
+       VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore));
+
+       return vk::check<VkSemaphore>(semaphore);
+}
+
+tcu::TestStatus testSemaphores (Context& context)
+{
+       TestLog&                                        log                                     = context.getTestContext().getLog();
+       const DeviceInterface&          deviceInterface         = context.getDeviceInterface();
+       const InstanceInterface&        instanceInterface       = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice          = context.getPhysicalDevice();
+       vk::Move<VkDevice>                      device                          = createTestDevice(instanceInterface, physicalDevice);
+       VkQueue                                         queue[2];
+       const deUint32                          queueFamilyIdx          = context.getUniversalQueueFamilyIndex();
+       VkResult                                        testStatus;
+       TestContext                                     testContext1(context, device.get());
+       TestContext                                     testContext2(context, device.get());
+       Unique<VkSemaphore>                     semaphore(createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL));
+       VkSubmitInfo                            submitInfo[2];
+       VkMappedMemoryRange                     range;
+       void*                                           resultImage;
+
+       deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
+       deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
+
+       const tcu::Vec4         vertices1[]                     =
+       {
+               tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+       };
+
+       const tcu::Vec4         vertices2[]                     =
+       {
+               tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+               tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+               tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+       };
+
+       testContext1.vertices = vertices1;
+       testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
+       testContext1.renderDimension = tcu::IVec2(256, 256);
+       testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
+
+       testContext2.vertices = vertices2;
+       testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
+       testContext2.renderDimension = tcu::IVec2(256, 256);
+       testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
+
+       createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
+       generateWork(testContext1);
+
+       createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
+       generateWork(testContext2);
+
+       initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
+
+       // The difference between the two submit infos is that each will use a unique cmd buffer,
+       // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
+       // semaphore but not signal a semaphore
+       submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
+       submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
+
+       submitInfo[0].signalSemaphoreCount = 1;
+       submitInfo[0].pSignalSemaphores = &semaphore.get();
+       submitInfo[1].waitSemaphoreCount = 1;
+       submitInfo[1].pWaitSemaphores = &semaphore.get();
+
+       VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
+
+       testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for a set fence");
+       }
+
+       range.sType                     = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+       range.pNext                     = DE_NULL;
+       range.memory            = testContext1.renderReadBuffer->getMemory();
+       range.offset            = 0;
+       range.size                      = testContext1.renderSize;
+       VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+       resultImage = testContext1.renderReadBuffer->getHostPtr();
+
+       log << TestLog::Image(  "result",
+                                                       "result",
+                                                       tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                       tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+                                                                       testContext1.renderDimension.x(),
+                                                                       testContext1.renderDimension.y(),
+                                                                       1,
+                                                                       resultImage));
+
+       VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
+
+       testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for a set fence");
+       }
+
+       range.sType                     = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+       range.pNext                     = DE_NULL;
+       range.memory            = testContext2.renderReadBuffer->getMemory();
+       range.offset            = 0;
+       range.size                      = testContext2.renderSize;
+       VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+       resultImage = testContext2.renderReadBuffer->getHostPtr();
+
+       log << TestLog::Image(  "result",
+                                                       "result",
+                                                       tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                       tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+                                                                       testContext2.renderDimension.x(),
+                                                                       testContext2.renderDimension.y(),
+                                                                       1,
+                                                                       resultImage));
+
+       return tcu::TestStatus::pass("synchronization-semaphores passed");
+}
+
+vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
+{
+       VkEventCreateInfo               eventCreateInfo;
+       VkEvent                                 event;
+
+       eventCreateInfo.sType           = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+       eventCreateInfo.pNext           = DE_NULL;
+       eventCreateInfo.flags           = 0;
+       VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event));
+
+       return vk::check<VkEvent>(event);
+}
+
+tcu::TestStatus testEvents (Context& context)
+{
+       TestLog&                                        log                                     = context.getTestContext().getLog();
+       const DeviceInterface&          deviceInterface         = context.getDeviceInterface();
+       const InstanceInterface&        instanceInterface       = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice          = context.getPhysicalDevice();
+       vk::Move<VkDevice>                      device                          = createTestDevice(instanceInterface, physicalDevice);
+       VkQueue                                         queue[2];
+       const deUint32                          queueFamilyIdx          = context.getUniversalQueueFamilyIndex();
+       VkResult                                        testStatus;
+       VkResult                                        eventStatus;
+       TestContext                                     testContext1(context, device.get());
+       TestContext                                     testContext2(context, device.get());
+       Unique<VkEvent>                         event(createEvent(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device.get(), DE_NULL));
+       VkSubmitInfo                            submitInfo[2];
+       VkMappedMemoryRange                     range;
+       void*                                           resultImage;
+
+       deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
+       deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
+
+       const tcu::Vec4         vertices1[]                     =
+       {
+               tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+               tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+       };
+
+       const tcu::Vec4         vertices2[]                     =
+       {
+               tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+               tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+               tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+       };
+
+       testContext1.vertices = vertices1;
+       testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
+       testContext1.renderDimension = tcu::IVec2(256, 256);
+       testContext1.setEvent = DE_TRUE;
+       testContext1.event = event.get();
+       testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
+
+       testContext2.vertices = vertices2;
+       testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
+       testContext2.renderDimension = tcu::IVec2(256, 256);
+       testContext2.waitEvent = DE_TRUE;
+       testContext2.event = event.get();
+       testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
+
+       createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
+       generateWork(testContext1);
+
+       createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
+       generateWork(testContext2);
+
+       initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
+       submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
+       submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
+
+       eventStatus = deviceInterface.getEventStatus(device.get(), event.get());
+       if (eventStatus != VK_EVENT_RESET)
+       {
+               log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << eventStatus << TestLog::EndMessage;
+               return tcu::TestStatus::fail("Event in incorrect status");
+       }
+
+       // Now the two contexts are submitted normally, so, context1 and set the event and context2 can wait for the event
+       VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
+       VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
+
+       testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for set fence");
+       }
+
+       range.sType                     = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+       range.pNext                     = DE_NULL;
+       range.memory            = testContext1.renderReadBuffer->getMemory();
+       range.offset            = 0;
+       range.size                      = testContext1.renderSize;
+       VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+       resultImage = testContext1.renderReadBuffer->getHostPtr();
+
+       log << TestLog::Image(  "result",
+                                                       "result",
+                                                       tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                       tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+                                                                       testContext1.renderDimension.x(),
+                                                                       testContext1.renderDimension.y(),
+                                                                       1,
+                                                                       resultImage));
+
+       testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+       if (testStatus != VK_SUCCESS)
+       {
+               log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+               return tcu::TestStatus::fail("failed to wait for a set fence");
+       }
+
+       range.sType                     = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+       range.pNext                     = DE_NULL;
+       range.memory            = testContext2.renderReadBuffer->getMemory();
+       range.offset            = 0;
+       range.size                      = testContext2.renderSize;
+       VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+       resultImage = testContext2.renderReadBuffer->getHostPtr();
+
+       log << TestLog::Image(  "result",
+                                                       "result",
+                                                       tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                       tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+                                                                       testContext2.renderDimension.x(),
+                                                                       testContext2.renderDimension.y(),
+                                                                       1,
+                                                                       resultImage));
+
+       return tcu::TestStatus::pass("synchronization-events passed");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createSynchronizationTests (tcu::TestContext& textCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> synchTests  (new tcu::TestCaseGroup(textCtx, "synchronization", "Vulkan Synchronization Tests"));
+
+       addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
+       addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
+       addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
+
+       return synchTests.release();
+}
+
+
+}; // vkt
diff --git a/external/vulkancts/modules/vulkan/vktSynchronization.hpp b/external/vulkancts/modules/vulkan/vktSynchronization.hpp
new file mode 100644 (file)
index 0000000..44c4585
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _VKTSYNCHRONIZATION_HPP
+#define _VKTSYNCHRONIZATION_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Platform Synchronization tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+
+tcu::TestCaseGroup*            createSynchronizationTests              (tcu::TestContext& testCtx);
+
+} // vkt
+
+#endif // _VKTSYNCHRONIZATION_HPP
index 3b50384..52aca99 100644 (file)
@@ -68,6 +68,7 @@
 #include "vktImageTests.hpp"
 #include "vktInfoTests.hpp"
 #include "vktWsiTests.hpp"
+#include "vktSynchronization.hpp"
 
 #include <vector>
 #include <sstream>
@@ -323,6 +324,7 @@ void TestPackage::init (void)
        addChild(compute::createTests           (m_testCtx));
        addChild(image::createTests                     (m_testCtx));
        addChild(wsi::createTests                       (m_testCtx));
+       addChild(createSynchronizationTests     (m_testCtx));
 }
 
 } // vkt
index 9f36f47..e33ecbf 100644 (file)
@@ -125,10 +125,11 @@ void shader_source (NegativeTestContext& ctx)
 
 void compile_shader (NegativeTestContext& ctx)
 {
-       // \note Shader compilation must be supported.
+       const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+       ctx.glDeleteShader(notAShader);
 
        ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
-       ctx.glCompileShader(9);
+       ctx.glCompileShader(notAShader);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -143,8 +144,11 @@ void compile_shader (NegativeTestContext& ctx)
 
 void delete_shader (NegativeTestContext& ctx)
 {
+       const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+       ctx.glDeleteShader(notAShader);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
-       ctx.glDeleteShader(9);
+       ctx.glDeleteShader(notAShader);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 }
@@ -231,6 +235,12 @@ void attach_shader (NegativeTestContext& ctx)
        GLuint shader2 = ctx.glCreateShader(GL_VERTEX_SHADER);
        GLuint program = ctx.glCreateProgram();
 
+       const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+       const GLuint notAProgram = ctx.glCreateProgram();
+
+       ctx.glDeleteShader(notAShader);
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
        ctx.glAttachShader(shader1, shader1);
        ctx.expectError(GL_INVALID_OPERATION);
@@ -244,11 +254,11 @@ void attach_shader (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
-       ctx.glAttachShader(program, -1);
+       ctx.glAttachShader(program, notAShader);
        ctx.expectError(GL_INVALID_VALUE);
-       ctx.glAttachShader(-1, shader1);
+       ctx.glAttachShader(notAProgram, shader1);
        ctx.expectError(GL_INVALID_VALUE);
-       ctx.glAttachShader(-1, -1);
+       ctx.glAttachShader(notAProgram, notAShader);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -274,12 +284,18 @@ void detach_shader (NegativeTestContext& ctx)
        GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
        GLuint program = ctx.glCreateProgram();
 
+       const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+       const GLuint notAProgram = ctx.glCreateProgram();
+
+       ctx.glDeleteShader(notAShader);
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
-       ctx.glDetachShader(-1, shader);
+       ctx.glDetachShader(notAProgram, shader);
        ctx.expectError(GL_INVALID_VALUE);
-       ctx.glDetachShader(program, -1);
+       ctx.glDetachShader(program, notAShader);
        ctx.expectError(GL_INVALID_VALUE);
-       ctx.glDetachShader(-1, -1);
+       ctx.glDetachShader(notAProgram, notAShader);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -308,8 +324,11 @@ void link_program (NegativeTestContext& ctx)
 {
        GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-       ctx.glLinkProgram(-1);
+       ctx.glLinkProgram(notAProgram);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -353,8 +372,11 @@ void use_program (NegativeTestContext& ctx)
 {
        GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
-       ctx.glUseProgram(-1);
+       ctx.glUseProgram(notAProgram);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -404,8 +426,11 @@ void delete_program (NegativeTestContext& ctx)
 {
        GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-       ctx.glDeleteProgram(-1);
+       ctx.glDeleteProgram(notAProgram);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -421,8 +446,11 @@ void validate_program (NegativeTestContext& ctx)
 {
        GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-       ctx.glValidateProgram(-1);
+       ctx.glValidateProgram(notAProgram);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -513,8 +541,11 @@ void program_parameteri (NegativeTestContext& ctx)
        GLuint program  = ctx.glCreateProgram();
        GLuint shader   = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of an existing program object.");
-       ctx.glProgramParameteri(0, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
+       ctx.glProgramParameteri(notAProgram, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -809,6 +840,9 @@ void get_attrib_location (NegativeTestContext& ctx)
 
        glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
        ctx.glBindAttribLocation                (programEmpty, 0, "test");
        ctx.glGetAttribLocation                 (programEmpty, "test");
@@ -821,7 +855,7 @@ void get_attrib_location (NegativeTestContext& ctx)
        ctx.expectError                         (GL_NO_ERROR);
        ctx.glGetAttribLocation                 (program.getProgram(), "test");
        ctx.expectError                         (GL_NO_ERROR);
-       ctx.glGetAttribLocation                 (-2, "test");
+       ctx.glGetAttribLocation                 (notAProgram, "test");
        ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -842,6 +876,9 @@ void get_uniform_location (NegativeTestContext& ctx)
 
        glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
        ctx.glGetUniformLocation(programEmpty, "test");
        ctx.expectError(GL_INVALID_OPERATION);
@@ -849,7 +886,7 @@ void get_uniform_location (NegativeTestContext& ctx)
 
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
        ctx.glUseProgram(program.getProgram());
-       ctx.glGetUniformLocation(-2, "test");
+       ctx.glGetUniformLocation(notAProgram, "test");
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -2142,6 +2179,9 @@ void get_transform_feedback_varying (NegativeTestContext& ctx)
        GLenum                                  type;
        char                                    name[32];
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.glGenTransformFeedbacks                             (1, &tfID);
 
        ctx.glTransformFeedbackVaryings                 (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
@@ -2153,7 +2193,7 @@ void get_transform_feedback_varying (NegativeTestContext& ctx)
        ctx.expectError                                         (GL_NO_ERROR);
 
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
-       ctx.glGetTransformFeedbackVarying               (-1, 0, 32, &length, &size, &type, &name[0]);
+       ctx.glGetTransformFeedbackVarying               (notAProgram, 0, 32, &length, &size, &type, &name[0]);
        ctx.expectError                                         (GL_INVALID_VALUE);
        ctx.endSection();
 
@@ -2175,21 +2215,23 @@ void get_transform_feedback_varying (NegativeTestContext& ctx)
 void transform_feedback_varyings (NegativeTestContext& ctx)
 {
        GLuint                                                                          tfID = 0;
-       GLuint shader                                                           = -1;
+       GLuint shader                                                           = ctx.glCreateShader(GL_VERTEX_SHADER);
        glu::ShaderProgram program                                      (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
        const char* tfVarying                                           = "gl_Position";
        GLint maxTransformFeedbackSeparateAttribs       = 0;
 
+       const GLuint notAProgram = ctx.glCreateProgram();
+       ctx.glDeleteProgram(notAProgram);
+
        ctx.glGenTransformFeedbacks                             (1, &tfID);
        ctx.expectError                                         (GL_NO_ERROR);
 
        ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
-       ctx.glTransformFeedbackVaryings                 (0, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
+       ctx.glTransformFeedbackVaryings                 (notAProgram, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
        ctx.expectError                                         (GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_OPERATION is generated if program is the name of a shader object.");
-       shader = ctx.glCreateShader(GL_VERTEX_SHADER);
        ctx.glTransformFeedbackVaryings(shader, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
        ctx.expectError(GL_INVALID_OPERATION);
        ctx.glDeleteShader(shader);