Merge vk-gl-cts/master into vk-gl-cts/vulkan-cts-next-dev
authorAlexander Galazin <alexander.galazin@arm.com>
Thu, 9 May 2019 11:20:25 +0000 (13:20 +0200)
committerAlexander Galazin <alexander.galazin@arm.com>
Thu, 9 May 2019 12:36:40 +0000 (14:36 +0200)
Change-Id: I8e9ee3f80d120ed3d8833c6c5187399a0f1dd3cd

1  2 
external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp

index cadc954,0000000..edeaef0
mode 100644,000000..100644
--- /dev/null
@@@ -1,2698 -1,0 +1,2681 @@@
- VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                   bufferSize,
-                                                                                const VkBufferUsageFlags       usage)
- {
-       const VkBufferCreateInfo bufferCreateInfo =
-       {
-               VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   //  VkStructureType             sType;
-               DE_NULL,                                                                //  const void*                 pNext;
-               (VkBufferCreateFlags)0,                                 //  VkBufferCreateFlags flags;
-               bufferSize,                                                             //  VkDeviceSize                size;
-               usage,                                                                  //  VkBufferUsageFlags  usage;
-               VK_SHARING_MODE_EXCLUSIVE,                              //  VkSharingMode               sharingMode;
-               0u,                                                                             //  deUint32                    queueFamilyIndexCount;
-               DE_NULL,                                                                //  const deUint32*             pQueueFamilyIndices;
-       };
-       return bufferCreateInfo;
- }
 +/*------------------------------------------------------------------------
 + * Vulkan Conformance Tests
 + * ------------------------
 + *
 + * Copyright (c) 2019 The Khronos Group Inc.
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + *
 + *//*!
 + * \file
 + * \brief Vulkan Imageless Framebuffer Tests
 + *//*--------------------------------------------------------------------*/
 +
 +#include "vktImagelessFramebufferTests.hpp"
 +#include "vktTestGroupUtil.hpp"
 +#include "vktTestCase.hpp"
 +
 +#include "deUniquePtr.hpp"
 +#include "deRandom.hpp"
 +
 +#include "tcuTextureUtil.hpp"
 +#include "tcuVectorUtil.hpp"
 +#include "tcuImageCompare.hpp"
 +#include "tcuRGBA.hpp"
 +
 +#include "vkCmdUtil.hpp"
 +#include "vkImageUtil.hpp"
 +#include "vkObjUtil.hpp"
 +#include "vkQueryUtil.hpp"
 +#include "vkRefUtil.hpp"
 +#include "vkTypeUtil.hpp"
 +#include "vkBuilderUtil.hpp"
 +
 +#include <iostream>
 +
 +namespace vkt
 +{
 +namespace imageless
 +{
 +
 +namespace
 +{
 +using namespace vk;
 +using de::MovePtr;
 +using de::UniquePtr;
 +using de::SharedPtr;
 +
 +typedef SharedPtr<Unique<VkPipeline> >        SharedPtrVkPipeline;
 +
 +enum TestType
 +{
 +      TEST_TYPE_COLOR = 0,
 +      TEST_TYPE_DEPTH_STENCIL,
 +      TEST_TYPE_COLOR_RESOLVE,
 +      TEST_TYPE_DEPTH_STENCIL_RESOLVE,
 +      TEST_TYPE_MULTISUBPASS,
 +      TEST_TYPE_LAST
 +};
 +
 +enum AspectFlagBits
 +{
 +      ASPECT_NONE                             = 0,
 +      ASPECT_COLOR                    = (1<<0),
 +      ASPECT_DEPTH                    = (1<<1),
 +      ASPECT_STENCIL                  = (1<<2),
 +      ASPECT_DEPTH_STENCIL    = ASPECT_DEPTH | ASPECT_STENCIL,
 +};
 +typedef deUint32 AspectFlags;
 +
 +const deUint32        NO_SAMPLE       = static_cast<deUint32>(-1);
 +const deUint32        NO_SUBPASS      = static_cast<deUint32>(-1);
 +
 +struct TestParameters
 +{
 +      TestType        testType;
 +      VkFormat        colorFormat;
 +      VkFormat        dsFormat;
 +};
 +
 +template<typename T>
 +inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
 +{
 +      return SharedPtr<Unique<T> >(new Unique<T>(move));
 +}
 +
 +VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
 +{
 +      switch (count)
 +      {
 +              case 1:  return VK_SAMPLE_COUNT_1_BIT;
 +              case 2:  return VK_SAMPLE_COUNT_2_BIT;
 +              case 4:  return VK_SAMPLE_COUNT_4_BIT;
 +              case 8:  return VK_SAMPLE_COUNT_8_BIT;
 +              case 16: return VK_SAMPLE_COUNT_16_BIT;
 +              case 32: return VK_SAMPLE_COUNT_32_BIT;
 +              case 64: return VK_SAMPLE_COUNT_64_BIT;
 +
 +              default:
 +                      DE_FATAL("Invalid sample count");
 +                      return (VkSampleCountFlagBits)0x0;
 +      }
 +}
 +
 +VkAttachmentReference2KHR convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask)
 +{
 +      const VkAttachmentReference2KHR attachmentReference2    =
 +      {
 +              VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,   //  VkStructureType             sType;
 +              DE_NULL,                                                                                //  const void*                 pNext;
 +              attachmentReference.attachment,                                 //  deUint32                    attachment;
 +              attachmentReference.layout,                                             //  VkImageLayout               layout;
 +              aspectMask                                                                              //  VkImageAspectFlags  aspectMask;
 +      };
 +
 +      return attachmentReference2;
 +}
 +
 +std::vector<VkAttachmentDescription2KHR> convertAttachmentDescriptions (const std::vector<VkAttachmentDescription>& attachmentDescriptions)
 +{
 +      std::vector<VkAttachmentDescription2KHR>        attachmentDescriptions2;
 +
 +      attachmentDescriptions2.reserve(attachmentDescriptions.size());
 +
 +      for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx)
 +      {
 +              const VkAttachmentDescription&          attachmentDescription   = attachmentDescriptions[adNdx];
 +              const VkAttachmentDescription2KHR       attachmentDescription2  =
 +              {
 +                      VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR, //  VkStructureType                                     sType;
 +                      DE_NULL,                                                                                //  const void*                                         pNext;
 +                      attachmentDescription.flags,                                    //  VkAttachmentDescriptionFlags        flags;
 +                      attachmentDescription.format,                                   //  VkFormat                                            format;
 +                      attachmentDescription.samples,                                  //  VkSampleCountFlagBits                       samples;
 +                      attachmentDescription.loadOp,                                   //  VkAttachmentLoadOp                          loadOp;
 +                      attachmentDescription.storeOp,                                  //  VkAttachmentStoreOp                         storeOp;
 +                      attachmentDescription.stencilLoadOp,                    //  VkAttachmentLoadOp                          stencilLoadOp;
 +                      attachmentDescription.stencilStoreOp,                   //  VkAttachmentStoreOp                         stencilStoreOp;
 +                      attachmentDescription.initialLayout,                    //  VkImageLayout                                       initialLayout;
 +                      attachmentDescription.finalLayout,                              //  VkImageLayout                                       finalLayout;
 +              };
 +
 +              attachmentDescriptions2.push_back(attachmentDescription2);
 +      }
 +
 +      return attachmentDescriptions2;
 +}
 +
 +Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&             vk,
 +                                                                                 const VkDevice                               device,
 +                                                                                 const deUint32                               setLayoutCount  = 0,
 +                                                                                 const VkDescriptorSetLayout* pSetLayouts             = DE_NULL)
 +{
 +      const VkPipelineLayoutCreateInfo        pipelineLayoutCreateInfo        =
 +      {
 +              VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //  VkStructureType                                     sType;
 +              DE_NULL,                                                                                //  const void*                                         pNext;
 +              (VkPipelineLayoutCreateFlags)0,                                 //  VkPipelineLayoutCreateFlags         flags;
 +              setLayoutCount,                                                                 //  deUint32                                            setLayoutCount;
 +              pSetLayouts,                                                                    //  const VkDescriptorSetLayout*        pSetLayouts;
 +              0u,                                                                                             //  deUint32                                            pushConstantRangeCount;
 +              DE_NULL,                                                                                //  const VkPushConstantRange*          pPushConstantRanges;
 +      };
 +
 +      return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
 +}
 +
 +Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&         vk,
 +                                                                         const VkDevice                               device,
 +                                                                         const VkPipelineLayout               pipelineLayout,
 +                                                                         const VkRenderPass                   renderPass,
 +                                                                         const VkShaderModule                 vertexModule,
 +                                                                         const VkShaderModule                 fragmendModule,
 +                                                                         const VkExtent2D                             renderSize,
 +                                                                         const AspectFlags                    depthStencilAspects     = ASPECT_NONE,
 +                                                                         const VkSampleCountFlagBits  sampleCountBits         = VK_SAMPLE_COUNT_1_BIT,
 +                                                                         const deUint32                               subpass                         = 0)
 +{
 +      const bool                                                                      useDepth                                                = (depthStencilAspects & ASPECT_DEPTH) != 0;
 +      const bool                                                                      useStencil                                              = (depthStencilAspects & ASPECT_STENCIL) != 0;
 +      const std::vector<VkViewport>                           viewports                                               (1, makeViewport(renderSize));
 +      const std::vector<VkRect2D>                                     scissors                                                (1, makeRect2D(renderSize));
 +      const VkStencilOpState                                          stencilOpState                                  =
 +      {
 +              VK_STENCIL_OP_KEEP,                                     //  VkStencilOp failOp;
 +              VK_STENCIL_OP_INCREMENT_AND_CLAMP,      //  VkStencilOp passOp;
 +              VK_STENCIL_OP_KEEP,                                     //  VkStencilOp depthFailOp;
 +              VK_COMPARE_OP_ALWAYS,                           //  VkCompareOp compareOp;
 +              ~0u,                                                            //  deUint32    compareMask;
 +              ~0u,                                                            //  deUint32    writeMask;
 +              0u                                                                      //  deUint32    reference;
 +      };
 +      const VkPipelineDepthStencilStateCreateInfo     pipelineDepthStencilStateInfo   =
 +      {
 +              VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     //  VkStructureType                                                     sType;
 +              DE_NULL,                                                                                                        //  const void*                                                         pNext;
 +              (VkPipelineDepthStencilStateCreateFlags)0,                                      //  VkPipelineDepthStencilStateCreateFlags      flags;
 +              useDepth ? VK_TRUE : VK_FALSE,                                                          //  VkBool32                                                            depthTestEnable;
 +              useDepth ? VK_TRUE : VK_FALSE,                                                          //  VkBool32                                                            depthWriteEnable;
 +              VK_COMPARE_OP_LESS,                                                                                     //  VkCompareOp                                                         depthCompareOp;
 +              VK_FALSE,                                                                                                       //  VkBool32                                                            depthBoundsTestEnable;
 +              useStencil ? VK_TRUE : VK_FALSE,                                                        //  VkBool32                                                            stencilTestEnable;
 +              stencilOpState,                                                                                         //  VkStencilOpState                                            front;
 +              stencilOpState,                                                                                         //  VkStencilOpState                                            back;
 +              0.0f,                                                                                                           //  float                                                                       minDepthBounds;
 +              1.0f                                                                                                            //  float                                                                       maxDepthBounds;
 +      };
 +      const VkPipelineMultisampleStateCreateInfo      multisampleState                                =
 +      {
 +              VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       //  VkStructureType                                                     sType;
 +              DE_NULL,                                                                                                        //  const void*                                                         pNext;
 +              (VkPipelineMultisampleStateCreateFlags)0u,                                      //  VkPipelineMultisampleStateCreateFlags       flags;
 +              sampleCountBits,                                                                                        //  VkSampleCountFlagBits                                       rasterizationSamples;
 +              VK_FALSE,                                                                                                       //  VkBool32                                                            sampleShadingEnable;
 +              0.0f,                                                                                                           //  float                                                                       minSampleShading;
 +              DE_NULL,                                                                                                        //  const VkSampleMask*                                         pSampleMask;
 +              VK_FALSE,                                                                                                       //  VkBool32                                                            alphaToCoverageEnable;
 +              VK_FALSE,                                                                                                       //  VkBool32                                                            alphaToOneEnable;
 +      };
 +
 +      return makeGraphicsPipeline(vk,                                                                 //  const DeviceInterface&                                                      vk
 +                                                              device,                                                         //  const VkDevice                                                                      device
 +                                                              pipelineLayout,                                         //  const VkPipelineLayout                                                      pipelineLayout
 +                                                              vertexModule,                                           //  const VkShaderModule                                                        vertexShaderModule
 +                                                              DE_NULL,                                                        //  const VkShaderModule                                                        tessellationControlModule
 +                                                              DE_NULL,                                                        //  const VkShaderModule                                                        tessellationEvalModule
 +                                                              DE_NULL,                                                        //  const VkShaderModule                                                        geometryShaderModule
 +                                                              fragmendModule,                                         //  const VkShaderModule                                                        fragmentShaderModule
 +                                                              renderPass,                                                     //  const VkRenderPass                                                          renderPass
 +                                                              viewports,                                                      //  const std::vector<VkViewport>&                                      viewports
 +                                                              scissors,                                                       //  const std::vector<VkRect2D>&                                        scissors
 +                                                              VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,//  const VkPrimitiveTopology                                               topology
 +                                                              subpass,                                                        //  const deUint32                                                                      subpass
 +                                                              0u,                                                                     //  const deUint32                                                                      patchControlPoints
 +                                                              DE_NULL,                                                        //  const VkPipelineVertexInputStateCreateInfo*         vertexInputStateCreateInfo
 +                                                              DE_NULL,                                                        //  const VkPipelineRasterizationStateCreateInfo*       rasterizationStateCreateInfo
 +                                                              &multisampleState,                                      //  const VkPipelineMultisampleStateCreateInfo*         multisampleStateCreateInfo
 +                                                              &pipelineDepthStencilStateInfo);        //  const VkPipelineDepthStencilStateCreateInfo*        depthStencilStateCreateInfo
 +}
 +
 +Move<VkRenderPass> makeRenderPass (const DeviceInterface&                             vk,
 +                                                                 const VkDevice                                               device,
 +                                                                 const VkFormat                                               colorFormat,
 +                                                                 const VkFormat                                               depthStencilFormat,
 +                                                                 const VkSampleCountFlagBits                  colorSamples,
 +                                                                 const VkSampleCountFlagBits                  depthStencilSamples                     = VK_SAMPLE_COUNT_1_BIT,
 +                                                                 const VkAttachmentLoadOp                             loadOperation                           = VK_ATTACHMENT_LOAD_OP_CLEAR,
 +                                                                 const VkImageLayout                                  finalLayoutColor                        = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
 +                                                                 const VkImageLayout                                  finalLayoutDepthStencil         = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
 +                                                                 const VkImageLayout                                  subpassLayoutColor                      = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
 +                                                                 const VkImageLayout                                  subpassLayoutDepthStencil       = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
 +                                                                 const VkAllocationCallbacks* const   allocationCallbacks                     = DE_NULL)
 +{
 +      const bool                                                              hasColor                                                                        = colorFormat != VK_FORMAT_UNDEFINED;
 +      const bool                                                              hasDepthStencil                                                         = depthStencilFormat != VK_FORMAT_UNDEFINED;
 +      const bool                                                              hasColorResolve                                                         = hasColor && (colorSamples != VK_SAMPLE_COUNT_1_BIT);
 +      const bool                                                              hasDepthStencilResolve                                          = hasDepthStencil && (depthStencilSamples != VK_SAMPLE_COUNT_1_BIT);
 +      const VkImageLayout                                             initialLayoutColor                                                      = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
 +      const VkImageLayout                                             initialLayoutDepthStencil                                       = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
 +      const VkAttachmentDescription                   colorAttachmentDescription                                      =
 +      {
 +              (VkAttachmentDescriptionFlags)0,                //  VkAttachmentDescriptionFlags        flags;
 +              colorFormat,                                                    //  VkFormat                                            format;
 +              colorSamples,                                                   //  VkSampleCountFlagBits                       samples;
 +              loadOperation,                                                  //  VkAttachmentLoadOp                          loadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         storeOp;
 +              VK_ATTACHMENT_LOAD_OP_DONT_CARE,                //  VkAttachmentLoadOp                          stencilLoadOp;
 +              VK_ATTACHMENT_STORE_OP_DONT_CARE,               //  VkAttachmentStoreOp                         stencilStoreOp;
 +              initialLayoutColor,                                             //  VkImageLayout                                       initialLayout;
 +              finalLayoutColor                                                //  VkImageLayout                                       finalLayout;
 +      };
 +      const VkAttachmentDescription                   depthStencilAttachmentDescription                       =
 +      {
 +              (VkAttachmentDescriptionFlags)0,                //  VkAttachmentDescriptionFlags        flags;
 +              depthStencilFormat,                                             //  VkFormat                                            format;
 +              depthStencilSamples,                                    //  VkSampleCountFlagBits                       samples;
 +              loadOperation,                                                  //  VkAttachmentLoadOp                          loadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         storeOp;
 +              loadOperation,                                                  //  VkAttachmentLoadOp                          stencilLoadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         stencilStoreOp;
 +              initialLayoutDepthStencil,                              //  VkImageLayout                                       initialLayout;
 +              finalLayoutDepthStencil                                 //  VkImageLayout                                       finalLayout;
 +      };
 +      const VkAttachmentDescription                   colorResolveAttachmentDescription                       =
 +      {
 +              (VkAttachmentDescriptionFlags)0,                //  VkAttachmentDescriptionFlags        flags;
 +              colorFormat,                                                    //  VkFormat                                            format;
 +              VK_SAMPLE_COUNT_1_BIT,                                  //  VkSampleCountFlagBits                       samples;
 +              VK_ATTACHMENT_LOAD_OP_LOAD,                             //  VkAttachmentLoadOp                          loadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         storeOp;
 +              VK_ATTACHMENT_LOAD_OP_DONT_CARE,                //  VkAttachmentLoadOp                          stencilLoadOp;
 +              VK_ATTACHMENT_STORE_OP_DONT_CARE,               //  VkAttachmentStoreOp                         stencilStoreOp;
 +              initialLayoutColor,                                             //  VkImageLayout                                       initialLayout;
 +              finalLayoutColor                                                //  VkImageLayout                                       finalLayout;
 +      };
 +      const VkAttachmentDescription                   depthStencilResolveAttachmentDescription        =
 +      {
 +              (VkAttachmentDescriptionFlags)0,                //  VkAttachmentDescriptionFlags        flags;
 +              depthStencilFormat,                                             //  VkFormat                                            format;
 +              VK_SAMPLE_COUNT_1_BIT,                                  //  VkSampleCountFlagBits                       samples;
 +              VK_ATTACHMENT_LOAD_OP_LOAD,                             //  VkAttachmentLoadOp                          loadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         storeOp;
 +              VK_ATTACHMENT_LOAD_OP_LOAD,                             //  VkAttachmentLoadOp                          stencilLoadOp;
 +              VK_ATTACHMENT_STORE_OP_STORE,                   //  VkAttachmentStoreOp                         stencilStoreOp;
 +              initialLayoutDepthStencil,                              //  VkImageLayout                                       initialLayout;
 +              finalLayoutDepthStencil                                 //  VkImageLayout                                       finalLayout;
 +      };
 +      std::vector<VkAttachmentDescription>    attachmentDescriptions;
 +
 +      if (hasColor)
 +              attachmentDescriptions.push_back(colorAttachmentDescription);
 +      if (hasDepthStencil)
 +              attachmentDescriptions.push_back(depthStencilAttachmentDescription);
 +      if (hasColorResolve)
 +              attachmentDescriptions.push_back(colorResolveAttachmentDescription);
 +      if (hasDepthStencilResolve)
 +              attachmentDescriptions.push_back(depthStencilResolveAttachmentDescription);
 +
 +      deUint32                                                                attachmentCounter                                                               = 0;
 +      const VkAttachmentReference                             colorAttachmentRef                                                              =
 +      {
 +              hasColor ? attachmentCounter++ : 0u,                            //  deUint32            attachment;
 +              subpassLayoutColor                                                                      //  VkImageLayout       layout;
 +      };
 +      const VkAttachmentReference                             depthStencilAttachmentRef                                               =
 +      {
 +              hasDepthStencil ? attachmentCounter++ : 0u,                     //  deUint32            attachment;
 +              subpassLayoutDepthStencil                                                       //  VkImageLayout       layout;
 +      };
 +      const VkAttachmentReference                             colorResolveAttachmentRef                                               =
 +      {
 +              hasColorResolve ? attachmentCounter++ : 0u,                     //  deUint32            attachment;
 +              subpassLayoutColor                                                                      //  VkImageLayout       layout;
 +      };
 +
 +      if (hasDepthStencilResolve)
 +      {
 +              const VkImageAspectFlags                                                        colorAspectMask                                                 = VK_IMAGE_ASPECT_COLOR_BIT;
 +              const VkImageAspectFlags                                                        depthStencilAspectMask                                  = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
 +              const VkAttachmentReference2KHR                                         colorAttachmentRef2                                             = convertAttachmentReference(colorAttachmentRef, colorAspectMask);
 +              const VkAttachmentReference2KHR                                         depthStencilAttachmentRef2                              = convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
 +              const VkAttachmentReference2KHR                                         colorResolveAttachmentRef2                              = convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
 +              const VkAttachmentReference2KHR                                         depthStencilResolveAttachmentRef2               =
 +              {
 +                      VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,                   //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                //  const void*                 pNext;
 +                      hasDepthStencilResolve ? attachmentCounter++ : 0u,              //  deUint32                    attachment;
 +                      subpassLayoutDepthStencil,                                                              //  VkImageLayout               layout;
 +                      depthStencilAspectMask                                                                  //  VkImageAspectFlags  aspectMask;
 +              };
 +              const VkSubpassDescriptionDepthStencilResolveKHR        subpassDescriptionDepthStencilResolve   =
 +              {
 +                      VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,        //  VkStructureType                                             sType;
 +                      DE_NULL,                                                                                                                        //  const void*                                                 pNext;
 +                      VK_RESOLVE_MODE_AVERAGE_BIT_KHR,                                                                        //  VkResolveModeFlagBitsKHR                    depthResolveMode;
 +                      VK_RESOLVE_MODE_MAX_BIT_KHR,                                                                            //  VkResolveModeFlagBitsKHR                    stencilResolveMode;
 +                      &depthStencilResolveAttachmentRef2                                                                      //  const VkAttachmentReference2KHR*    pDepthStencilResolveAttachment;
 +              };
 +              const VkSubpassDescription2KHR                                          subpassDescription2                                             =
 +              {
 +                      VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,                            //  VkStructureType                                             sType;
 +                      &subpassDescriptionDepthStencilResolve,                                         //  const void*                                                 pNext;
 +                      (VkSubpassDescriptionFlags)0,                                                           //  VkSubpassDescriptionFlags                   flags;
 +                      VK_PIPELINE_BIND_POINT_GRAPHICS,                                                        //  VkPipelineBindPoint                                 pipelineBindPoint;
 +                      0u,                                                                                                                     //  deUint32                                                    viewMask;
 +                      0u,                                                                                                                     //  deUint32                                                    inputAttachmentCount;
 +                      DE_NULL,                                                                                                        //  const VkAttachmentReference2KHR*    pInputAttachments;
 +                      hasColor ? 1u : 0u,                                                                                     //  deUint32                                                    colorAttachmentCount;
 +                      hasColor ? &colorAttachmentRef2 : DE_NULL,                                      //  const VkAttachmentReference2KHR*    pColorAttachments;
 +                      hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL,        //  const VkAttachmentReference2KHR*    pResolveAttachments;
 +                      hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL,        //  const VkAttachmentReference2KHR*    pDepthStencilAttachment;
 +                      0u,                                                                                                                     //  deUint32                                                    preserveAttachmentCount;
 +                      DE_NULL                                                                                                         //  const deUint32*                                             pPreserveAttachments;
 +              };
 +              const std::vector<VkAttachmentDescription2KHR>          attachmentDescriptions2                                 = convertAttachmentDescriptions(attachmentDescriptions);
 +              const VkRenderPassCreateInfo2KHR                                        renderPassInfo                                                  =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,        //  VkStructureType                                             sType;
 +                      DE_NULL,                                                                                        //  const void*                                                 pNext;
 +                      (VkRenderPassCreateFlags)0,                                                     //  VkRenderPassCreateFlags                             flags;
 +                      (deUint32)attachmentDescriptions2.size(),                       //  deUint32                                                    attachmentCount;
 +                      &attachmentDescriptions2[0],                                            //  const VkAttachmentDescription2KHR*  pAttachments;
 +                      1u,                                                                                                     //  deUint32                                                    subpassCount;
 +                      &subpassDescription2,                                                           //  const VkSubpassDescription2KHR*             pSubpasses;
 +                      0u,                                                                                                     //  deUint32                                                    dependencyCount;
 +                      DE_NULL,                                                                                        //  const VkSubpassDependency2KHR*              pDependencies;
 +                      0u,                                                                                                     //  deUint32                                                    correlatedViewMaskCount;
 +                      DE_NULL                                                                                         //  const deUint32*                                             pCorrelatedViewMasks;
 +              };
 +
 +              return createRenderPass2KHR(vk, device, &renderPassInfo, allocationCallbacks);
 +      }
 +      else
 +      {
 +              const VkSubpassDescription                              subpassDescription                                                      =
 +              {
 +                      (VkSubpassDescriptionFlags)0,                                                   //  VkSubpassDescriptionFlags           flags;
 +                      VK_PIPELINE_BIND_POINT_GRAPHICS,                                                //  VkPipelineBindPoint                         pipelineBindPoint;
 +                      0u,                                                                                                             //  deUint32                                            inputAttachmentCount;
 +                      DE_NULL,                                                                                                //  const VkAttachmentReference*        pInputAttachments;
 +                      hasColor ? 1u : 0u,                                                                             //  deUint32                                            colorAttachmentCount;
 +                      hasColor ? &colorAttachmentRef : DE_NULL,                               //  const VkAttachmentReference*        pColorAttachments;
 +                      hasColorResolve ? &colorResolveAttachmentRef : DE_NULL, //  const VkAttachmentReference*        pResolveAttachments;
 +                      hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL, //  const VkAttachmentReference*        pDepthStencilAttachment;
 +                      0u,                                                                                                             //  deUint32                                            preserveAttachmentCount;
 +                      DE_NULL                                                                                                 //  const deUint32*                                     pPreserveAttachments;
 +              };
 +              const VkRenderPassCreateInfo                    renderPassInfo                                                          =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      //  VkStructureType                                     sType;
 +                      DE_NULL,                                                                        //  const void*                                         pNext;
 +                      (VkRenderPassCreateFlags)0,                                     //  VkRenderPassCreateFlags                     flags;
 +                      (deUint32)attachmentDescriptions.size(),        //  deUint32                                            attachmentCount;
 +                      &attachmentDescriptions[0],                                     //  const VkAttachmentDescription*      pAttachments;
 +                      1u,                                                                                     //  deUint32                                            subpassCount;
 +                      &subpassDescription,                                            //  const VkSubpassDescription*         pSubpasses;
 +                      0u,                                                                                     //  deUint32                                            dependencyCount;
 +                      DE_NULL                                                                         //  const VkSubpassDependency*          pDependencies;
 +              };
 +
 +              return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
 +      }
 +}
 +
 +Move<VkRenderPass> makeRenderPass (const DeviceInterface&                             vk,
 +                                                                 const VkDevice                                               device,
 +                                                                 const VkFormat                                               colorFormat,
 +                                                                 const VkAllocationCallbacks* const   allocationCallbacks)
 +{
 +      const VkAttachmentDescription   attachmentDescriptions[]        =
 +      {
 +              {
 +                      (VkAttachmentDescriptionFlags)0,                        //  VkAttachmentDescriptionFlags        flags;
 +                      colorFormat,                                                            //  VkFormat                                            format;
 +                      VK_SAMPLE_COUNT_1_BIT,                                          //  VkSampleCountFlagBits                       samples;
 +                      VK_ATTACHMENT_LOAD_OP_CLEAR,                            //  VkAttachmentLoadOp                          loadOp;
 +                      VK_ATTACHMENT_STORE_OP_STORE,                           //  VkAttachmentStoreOp                         storeOp;
 +                      VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        //  VkAttachmentLoadOp                          stencilLoadOp;
 +                      VK_ATTACHMENT_STORE_OP_DONT_CARE,                       //  VkAttachmentStoreOp                         stencilStoreOp;
 +                      VK_IMAGE_LAYOUT_UNDEFINED,                                      //  VkImageLayout                                       initialLayout;
 +                      VK_IMAGE_LAYOUT_GENERAL                                         //  VkImageLayout                                       finalLayout;
 +              },
 +              {
 +                      (VkAttachmentDescriptionFlags)0,                        //  VkAttachmentDescriptionFlags        flags;
 +                      colorFormat,                                                            //  VkFormat                                            format;
 +                      VK_SAMPLE_COUNT_1_BIT,                                          //  VkSampleCountFlagBits                       samples;
 +                      VK_ATTACHMENT_LOAD_OP_LOAD,                                     //  VkAttachmentLoadOp                          loadOp;
 +                      VK_ATTACHMENT_STORE_OP_STORE,                           //  VkAttachmentStoreOp                         storeOp;
 +                      VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        //  VkAttachmentLoadOp                          stencilLoadOp;
 +                      VK_ATTACHMENT_STORE_OP_DONT_CARE,                       //  VkAttachmentStoreOp                         stencilStoreOp;
 +                      VK_IMAGE_LAYOUT_UNDEFINED,                                      //  VkImageLayout                                       initialLayout;
 +                      VK_IMAGE_LAYOUT_GENERAL                                         //  VkImageLayout                                       finalLayout;
 +              },
 +      };
 +      const VkAttachmentReference             colorAttachmentRef0                     =
 +      {
 +              0u,                                                     //  deUint32            attachment;
 +              VK_IMAGE_LAYOUT_GENERAL         //  VkImageLayout       layout;
 +      };
 +      const deUint32                                  preserveAttachment                      = 1u;
 +      const VkAttachmentReference             inputAttachmentRef1                     =
 +      {
 +              0u,                                                     //  deUint32            attachment;
 +              VK_IMAGE_LAYOUT_GENERAL         //  VkImageLayout       layout;
 +      };
 +      const VkAttachmentReference             colorAttachmentRef1                     =
 +      {
 +              1u,                                                     //  deUint32            attachment;
 +              VK_IMAGE_LAYOUT_GENERAL         //  VkImageLayout       layout;
 +      };
 +      const VkSubpassDescription              subpassDescriptions[]           =
 +      {
 +              {
 +                      (VkSubpassDescriptionFlags)0,                           //  VkSubpassDescriptionFlags           flags;
 +                      VK_PIPELINE_BIND_POINT_GRAPHICS,                        //  VkPipelineBindPoint                         pipelineBindPoint;
 +                      0u,                                                                                     //  deUint32                                            inputAttachmentCount;
 +                      DE_NULL,                                                                        //  const VkAttachmentReference*        pInputAttachments;
 +                      1u,                                                                                     //  deUint32                                            colorAttachmentCount;
 +                      &colorAttachmentRef0,                                           //  const VkAttachmentReference*        pColorAttachments;
 +                      DE_NULL,                                                                        //  const VkAttachmentReference*        pResolveAttachments;
 +                      DE_NULL,                                                                        //  const VkAttachmentReference*        pDepthStencilAttachment;
 +                      1u,                                                                                     //  deUint32                                            preserveAttachmentCount;
 +                      &preserveAttachment                                                     //  const deUint32*                                     pPreserveAttachments;
 +              },
 +              {
 +                      (VkSubpassDescriptionFlags)0,                           //  VkSubpassDescriptionFlags           flags;
 +                      VK_PIPELINE_BIND_POINT_GRAPHICS,                        //  VkPipelineBindPoint                         pipelineBindPoint;
 +                      1u,                                                                                     //  deUint32                                            inputAttachmentCount;
 +                      &inputAttachmentRef1,                                           //  const VkAttachmentReference*        pInputAttachments;
 +                      1u,                                                                                     //  deUint32                                            colorAttachmentCount;
 +                      &colorAttachmentRef1,                                           //  const VkAttachmentReference*        pColorAttachments;
 +                      DE_NULL,                                                                        //  const VkAttachmentReference*        pResolveAttachments;
 +                      DE_NULL,                                                                        //  const VkAttachmentReference*        pDepthStencilAttachment;
 +                      0u,                                                                                     //  deUint32                                            preserveAttachmentCount;
 +                      DE_NULL                                                                         //  const deUint32*                                     pPreserveAttachments;
 +              },
 +      };
 +      const VkSubpassDependency               subpassDependency                       =
 +      {
 +              0,                                                                                              //  deUint32                                            srcSubpass;
 +              1u,                                                                                             //  deUint32                                            dstSubpass;
 +              VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  //  VkPipelineStageFlags                        srcStageMask;
 +              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                  //  VkPipelineStageFlags                        dstStageMask;
 +              VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   //  VkAccessFlags                                       srcAccessMask;
 +              VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                    //  VkAccessFlags                                       dstAccessMask;
 +              VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR,                               //  VkDependencyFlags                           dependencyFlags;
 +      };
 +      const VkRenderPassCreateInfo    renderPassInfo                          =
 +      {
 +              VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,              //  VkStructureType                                     sType;
 +              DE_NULL,                                                                                //  const void*                                         pNext;
 +              (VkRenderPassCreateFlags)0,                                             //  VkRenderPassCreateFlags                     flags;
 +              DE_LENGTH_OF_ARRAY(attachmentDescriptions),             //  deUint32                                            attachmentCount;
 +              &attachmentDescriptions[0],                                             //  const VkAttachmentDescription*      pAttachments;
 +              DE_LENGTH_OF_ARRAY(subpassDescriptions),                //  deUint32                                            subpassCount;
 +              &subpassDescriptions[0],                                                //  const VkSubpassDescription*         pSubpasses;
 +              1u,                                                                                             //  deUint32                                            dependencyCount;
 +              &subpassDependency                                                              //  const VkSubpassDependency*          pDependencies;
 +      };
 +
 +      return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
 +}
 +
 +VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const VkExtent2D size, const VkImageUsageFlags usage, VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT)
 +{
 +      const VkExtent3D                extent          = { size.width, size.height, 1u };
 +      const VkImageCreateInfo imageParams =
 +      {
 +              VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
 +              DE_NULL,                                                                                // const void*                          pNext;
 +              0u,                                                                                             // VkImageCreateFlags           flags;
 +              VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
 +              format,                                                                                 // VkFormat                                     format;
 +              extent,                                                                                 // VkExtent3D                           extent;
 +              1u,                                                                                             // deUint32                                     mipLevels;
 +              1u,                                                                                             // deUint32                                     arrayLayers;
 +              samples,                                                                                // VkSampleCountFlagBits        samples;
 +              VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
 +              usage,                                                                                  // VkImageUsageFlags            usage;
 +              VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
 +              0u,                                                                                             // deUint32                                     queueFamilyIndexCount;
 +              DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices;
 +              VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
 +      };
 +      return imageParams;
 +}
 +
 +std::vector<VkFramebufferAttachmentImageInfoKHR> makeFramebufferAttachmentImageInfos (const VkExtent2D&                       renderSize,
 +                                                                                                                                                                        const VkFormat                        colorFormat,
 +                                                                                                                                                                        const VkImageUsageFlags       colorUsage,
 +                                                                                                                                                                        const VkFormat                        dsFormat,
 +                                                                                                                                                                        const VkImageUsageFlags       dsUsage,
 +                                                                                                                                                                        const AspectFlags                     resolveAspects,
 +                                                                                                                                                                        const deUint32                        inputAttachmentCount)
 +{
 +      const bool                                                                                      colorResolve                                    = (resolveAspects & ASPECT_COLOR) != 0;
 +      const bool                                                                                      depthStencilResolve                             = (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
 +      std::vector<VkFramebufferAttachmentImageInfoKHR>        framebufferAttachmentImageInfos;
 +
 +      if (colorFormat != VK_FORMAT_UNDEFINED)
 +      {
 +              const VkFramebufferAttachmentImageInfoKHR       framebufferAttachmentImageInfo          =
 +              {
 +                      VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      (VkImageCreateFlags)0u,                                                                         //  VkImageCreateFlags  flags;
 +                      colorUsage,                                                                                                     //  VkImageUsageFlags   usage;
 +                      renderSize.width,                                                                                       //  deUint32                    width;
 +                      renderSize.height,                                                                                      //  deUint32                    height;
 +                      1u,                                                                                                                     //  deUint32                    layerCount;
 +                      1u,                                                                                                                     //  deUint32                    viewFormatCount;
 +                      &colorFormat                                                                                            //  const VkFormat*             pViewFormats;
 +              };
 +
 +              framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
 +      }
 +
 +      if (dsFormat != VK_FORMAT_UNDEFINED)
 +      {
 +              const VkFramebufferAttachmentImageInfoKHR       framebufferAttachmentImageInfo          =
 +              {
 +                      VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      (VkImageCreateFlags)0u,                                                                         //  VkImageCreateFlags  flags;
 +                      dsUsage,                                                                                                        //  VkImageUsageFlags   usage;
 +                      renderSize.width,                                                                                       //  deUint32                    width;
 +                      renderSize.height,                                                                                      //  deUint32                    height;
 +                      1u,                                                                                                                     //  deUint32                    layerCount;
 +                      1u,                                                                                                                     //  deUint32                    viewFormatCount;
 +                      &dsFormat                                                                                                       //  const VkFormat*             pViewFormats;
 +              };
 +
 +              framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
 +      }
 +
 +      if (colorResolve)
 +      {
 +              const VkFramebufferAttachmentImageInfoKHR       framebufferAttachmentImageInfo          =
 +              {
 +                      VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      (VkImageCreateFlags)0u,                                                                         //  VkImageCreateFlags  flags;
 +                      colorUsage,                                                                                                     //  VkImageUsageFlags   usage;
 +                      renderSize.width,                                                                                       //  deUint32                    width;
 +                      renderSize.height,                                                                                      //  deUint32                    height;
 +                      1u,                                                                                                                     //  deUint32                    layerCount;
 +                      1u,                                                                                                                     //  deUint32                    viewFormatCount;
 +                      &colorFormat                                                                                            //  const VkFormat*             pViewFormats;
 +              };
 +
 +              DE_ASSERT(colorFormat != VK_FORMAT_UNDEFINED);
 +
 +              framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
 +      }
 +
 +      if (depthStencilResolve)
 +      {
 +              const VkFramebufferAttachmentImageInfoKHR       framebufferAttachmentImageInfo          =
 +              {
 +                      VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      (VkImageCreateFlags)0u,                                                                         //  VkImageCreateFlags  flags;
 +                      dsUsage,                                                                                                        //  VkImageUsageFlags   usage;
 +                      renderSize.width,                                                                                       //  deUint32                    width;
 +                      renderSize.height,                                                                                      //  deUint32                    height;
 +                      1u,                                                                                                                     //  deUint32                    layerCount;
 +                      1u,                                                                                                                     //  deUint32                    viewFormatCount;
 +                      &dsFormat                                                                                                       //  const VkFormat*             pViewFormats;
 +              };
 +
 +              DE_ASSERT(dsFormat != VK_FORMAT_UNDEFINED);
 +
 +              framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
 +      }
 +
 +      for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx)
 +      {
 +              const VkFramebufferAttachmentImageInfoKHR       framebufferAttachmentImageInfo          =
 +              {
 +                      VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      (VkImageCreateFlags)0u,                                                                         //  VkImageCreateFlags  flags;
 +                      colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,                       //  VkImageUsageFlags   usage;
 +                      renderSize.width,                                                                                       //  deUint32                    width;
 +                      renderSize.height,                                                                                      //  deUint32                    height;
 +                      1u,                                                                                                                     //  deUint32                    layerCount;
 +                      1u,                                                                                                                     //  deUint32                    viewFormatCount;
 +                      &colorFormat                                                                                            //  const VkFormat*             pViewFormats;
 +              };
 +
 +              framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
 +      }
 +
 +      return framebufferAttachmentImageInfos;
 +}
 +
 +Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&                   vk,
 +                                                                       const VkDevice                                 device,
 +                                                                       const VkRenderPass                             renderPass,
 +                                                                       const VkExtent2D&                              renderSize,
 +                                                                       const VkFormat                                 colorFormat,
 +                                                                       const VkImageUsageFlags                colorUsage,
 +                                                                       const VkFormat                                 dsFormat                                = VK_FORMAT_UNDEFINED,
 +                                                                       const VkImageUsageFlags                dsUsage                                 = static_cast<VkImageUsageFlags>(0),
 +                                                                       const AspectFlags                              resolveAspects                  = ASPECT_NONE,
 +                                                                       const deUint32                                 inputAttachmentCount    = 0)
 +{
 +      const std::vector<VkFramebufferAttachmentImageInfoKHR>  framebufferAttachmentImageInfos         = makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount);
 +      const deUint32                                                                                  attachmentCount                                         = static_cast<deUint32>(framebufferAttachmentImageInfos.size());
 +      const VkFramebufferAttachmentsCreateInfoKHR                             framebufferAttachmentsCreateInfo        =
 +      {
 +              VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR,      //  VkStructureType                                                             sType;
 +              DE_NULL,                                                                                                        //  const void*                                                                 pNext;
 +              attachmentCount,                                                                                        //  deUint32                                                                    attachmentImageInfoCount;
 +              &framebufferAttachmentImageInfos[0]                                                     //  const VkFramebufferAttachmentImageInfoKHR*  pAttachmentImageInfos;
 +      };
 +      const VkFramebufferCreateInfo                                                   framebufferInfo =
 +      {
 +              VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                                      //  VkStructureType                             sType;
 +              &framebufferAttachmentsCreateInfo,                                                      //  const void*                                 pNext;
 +              VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR,                                        //  VkFramebufferCreateFlags    flags;
 +              renderPass,                                                                                                     //  VkRenderPass                                renderPass;
 +              attachmentCount,                                                                                        //  deUint32                                    attachmentCount;
 +              DE_NULL,                                                                                                        //  const VkImageView*                  pAttachments;
 +              renderSize.width,                                                                                       //  deUint32                                    width;
 +              renderSize.height,                                                                                      //  deUint32                                    height;
 +              1u,                                                                                                                     //  deUint32                                    layers;
 +      };
 +
 +      return createFramebuffer(vk, device, &framebufferInfo);
 +}
 +
 +Move<VkFramebuffer> makeVerifyFramebuffer (const DeviceInterface&     vk,
 +                                                                                 const VkDevice                       device,
 +                                                                                 const VkRenderPass           renderPass,
 +                                                                                 const VkImageView            colorAttachment,
 +                                                                                 const VkExtent2D&            renderSize,
 +                                                                                 const deUint32                       layers = 1u)
 +{
 +      const VkFramebufferCreateInfo framebufferInfo = {
 +              VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              //  VkStructureType                             sType;
 +              DE_NULL,                                                                                //  const void*                                 pNext;
 +              (VkFramebufferCreateFlags)0,                                    //  VkFramebufferCreateFlags    flags;
 +              renderPass,                                                                             //  VkRenderPass                                renderPass;
 +              1u,                                                                                             //  deUint32                                    attachmentCount;
 +              &colorAttachment,                                                               //  const VkImageView*                  pAttachments;
 +              renderSize.width,                                                               //  deUint32                                    width;
 +              renderSize.height,                                                              //  deUint32                                    height;
 +              layers,                                                                                 //  deUint32                                    layers;
 +      };
 +
 +      return createFramebuffer(vk, device, &framebufferInfo);
 +}
 +
 +Move<VkPipelineLayout> makeVerifyPipelineLayout (const DeviceInterface&                       vk,
 +                                                                                               const VkDevice                                 device,
 +                                                                                               const VkDescriptorSetLayout    descriptorSetLayout)
 +{
 +      const VkPushConstantRange                       pushConstantRanges                      =
 +      {
 +              VK_SHADER_STAGE_FRAGMENT_BIT,                                   //  VkShaderStageFlags                          stageFlags;
 +              0u,                                                                                             //  deUint32                                            offset;
 +              sizeof(deUint32)                                                                //  deUint32                                            size;
 +      };
 +      const VkPipelineLayoutCreateInfo        pipelineLayoutCreateInfo        =
 +      {
 +              VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //  VkStructureType                                     sType;
 +              DE_NULL,                                                                                //  const void*                                         pNext;
 +              (VkPipelineLayoutCreateFlags)0,                                 //  VkPipelineLayoutCreateFlags         flags;
 +              1u,                                                                                             //  deUint32                                            setLayoutCount;
 +              &descriptorSetLayout,                                                   //  const VkDescriptorSetLayout*        pSetLayouts;
 +              1u,                                                                                             //  deUint32                                            pushConstantRangeCount;
 +              &pushConstantRanges,                                                    //  const VkPushConstantRange*          pPushConstantRanges;
 +      };
 +      return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
 +}
 +
 +Move<VkRenderPass> makeVerifyRenderPass (const DeviceInterface&       vk,
 +                                                                               const VkDevice                 device,
 +                                                                               const VkFormat                 colorFormat)
 +{
 +      return makeRenderPass(vk, device, colorFormat);
 +}
 +
 +VkImageMemoryBarrier makeImageMemoryBarrier   (const VkAccessFlags                    srcAccessMask,
 +                                                                                       const VkAccessFlags                    dstAccessMask,
 +                                                                                       const VkImageLayout                    oldLayout,
 +                                                                                       const VkImageLayout                    newLayout,
 +                                                                                       const VkImage                                  image,
 +                                                                                       const VkImageSubresourceRange  subresourceRange)
 +{
 +      const VkImageMemoryBarrier barrier =
 +      {
 +              VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
 +              DE_NULL,                                                                                // const void*                          pNext;
 +              srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
 +              dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
 +              oldLayout,                                                                              // VkImageLayout                        oldLayout;
 +              newLayout,                                                                              // VkImageLayout                        newLayout;
 +              VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
 +              VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
 +              image,                                                                                  // VkImage                                      image;
 +              subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
 +      };
 +      return barrier;
 +}
 +
 +VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags    srcAccessMask,
 +                                                                                         const VkAccessFlags  dstAccessMask,
 +                                                                                         const VkBuffer               buffer,
 +                                                                                         const VkDeviceSize   offset,
 +                                                                                         const VkDeviceSize   bufferSizeBytes)
 +{
 +      const VkBufferMemoryBarrier barrier =
 +      {
 +              VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        //  VkStructureType     sType;
 +              DE_NULL,                                                                        //  const void*         pNext;
 +              srcAccessMask,                                                          //  VkAccessFlags       srcAccessMask;
 +              dstAccessMask,                                                          //  VkAccessFlags       dstAccessMask;
 +              VK_QUEUE_FAMILY_IGNORED,                                        //  deUint32            srcQueueFamilyIndex;
 +              VK_QUEUE_FAMILY_IGNORED,                                        //  deUint32            destQueueFamilyIndex;
 +              buffer,                                                                         //  VkBuffer            buffer;
 +              offset,                                                                         //  VkDeviceSize        offset;
 +              bufferSizeBytes,                                                        //  VkDeviceSize        size;
 +      };
 +      return barrier;
 +}
 +
 +VkBufferImageCopy makeBufferImageCopy (const VkExtent3D                                       extent,
 +                                                                         const VkImageSubresourceLayers       subresourceLayers)
 +{
 +      const VkBufferImageCopy copyParams =
 +      {
 +              0ull,                                                                           //      VkDeviceSize                            bufferOffset;
 +              0u,                                                                                     //      deUint32                                        bufferRowLength;
 +              0u,                                                                                     //      deUint32                                        bufferImageHeight;
 +              subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
 +              makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
 +              extent,                                                                         //      VkExtent3D                                      imageExtent;
 +      };
 +      return copyParams;
 +}
 +
 +inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo)
 +{
 +      return createBuffer(vk, device, &createInfo);
 +}
 +
 +inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
 +{
 +      return createImage(vk, device, &createInfo);
 +}
 +
 +MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
 +{
 +      MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
 +      VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
 +      return alloc;
 +}
 +
 +MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
 +{
 +      MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
 +      VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
 +      return alloc;
 +}
 +
 +Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
 +{
 +      const VkSamplerCreateInfo createInfo =
 +      {
 +              VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          //  VkStructureType                     sType;
 +              DE_NULL,                                                                        //  const void*                         pNext;
 +              0u,                                                                                     //  VkSamplerCreateFlags        flags;
 +              VK_FILTER_NEAREST,                                                      //  VkFilter                            magFilter;
 +              VK_FILTER_NEAREST,                                                      //  VkFilter                            minFilter;
 +              VK_SAMPLER_MIPMAP_MODE_LINEAR,                          //  VkSamplerMipmapMode         mipmapMode;
 +              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          //  VkSamplerAddressMode        addressModeU;
 +              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          //  VkSamplerAddressMode        addressModeV;
 +              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          //  VkSamplerAddressMode        addressModeW;
 +              0.0f,                                                                           //  float                                       mipLodBias;
 +              VK_FALSE,                                                                       //  VkBool32                            anisotropyEnable;
 +              1.0f,                                                                           //  float                                       maxAnisotropy;
 +              VK_FALSE,                                                                       //  VkBool32                            compareEnable;
 +              VK_COMPARE_OP_ALWAYS,                                           //  VkCompareOp                         compareOp;
 +              0.0f,                                                                           //  float                                       minLod;
 +              0.0f,                                                                           //  float                                       maxLod;
 +              VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,        //  VkBorderColor                       borderColor;
 +              VK_FALSE                                                                        //  VkBool32                            unnormalizedCoordinates;
 +      };
 +
 +      return createSampler(vk, device, &createInfo);
 +}
 +
 +void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, const void* data, const VkDeviceSize dataSize)
 +{
 +      const VkMappedMemoryRange       memRange                =
 +      {
 +              VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //  VkStructureType     sType;
 +              DE_NULL,                                                                //  const void*         pNext;
 +              bufferAlloc.getMemory(),                                //  VkDeviceMemory      memory;
 +              bufferAlloc.getOffset(),                                //  VkDeviceSize        offset;
 +              VK_WHOLE_SIZE                                                   //  VkDeviceSize        size;
 +      };
 +      const deUint32                          dataSize32              = static_cast<deUint32>(dataSize);
 +
 +      deMemcpy(bufferAlloc.getHostPtr(), data, dataSize32);
 +      VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
 +}
 +
 +std::vector<float> getFullQuadVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f, -1.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f, -1.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f, -1.0f, 0.0f, 1.0f,
 +              +1.0f, +1.0f, 0.0f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +void checkImageFormatProperties (const InstanceInterface&     vki,
 +                                                               const VkPhysicalDevice&        physDevice,
 +                                                               const VkFormat                         format,
 +                                                               const VkImageUsageFlags        imageUsageFlags,
 +                                                               const VkExtent2D&                      requiredSize2D)
 +{
 +      const VkImageType                       imageType                       = VK_IMAGE_TYPE_2D;
 +      const VkImageTiling                     imageTiling                     = VK_IMAGE_TILING_OPTIMAL;
 +      const VkImageCreateFlags        imageCreateFlags        = static_cast<VkImageCreateFlags>(0u);
 +      const deUint32                          requiredLayers          = 1u;
 +      const VkExtent3D                        requiredSize            = makeExtent3D(requiredSize2D.height, requiredSize2D.width, 1u);
 +
 +      VkImageFormatProperties imageFormatProperties;
 +      VkResult                                result;
 +
 +      deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties));
 +
 +      result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
 +
 +      if (result                                                                      != VK_SUCCESS                   ||
 +              imageFormatProperties.maxArrayLayers    <  requiredLayers               ||
 +              imageFormatProperties.maxExtent.height  <  requiredSize.height  ||
 +              imageFormatProperties.maxExtent.width   <  requiredSize.width   ||
 +              imageFormatProperties.maxExtent.depth   <  requiredSize.depth)
 +      {
 +              TCU_THROW(NotSupportedError, "Depth/stencil format is not supported");
 +      }
 +}
 +
 +VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat)
 +{
 +      const tcu::TextureFormat        tcuFormat       = mapVkFormat(depthStencilImageFormat);
 +      const VkFormat                          result          = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED;
 +
 +      DE_ASSERT(result != VK_FORMAT_UNDEFINED);
 +
 +      return result;
 +}
 +
 +static MovePtr<tcu::TextureLevel> convertDepthToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
 +{
 +      const tcu::ConstPixelBufferAccess       srcImage        (dataFormat, width, height, 1u, data);
 +      MovePtr<tcu::TextureLevel>                      dstImage        (new tcu::TextureLevel(targetFormat, width, height, 1u));
 +      tcu::PixelBufferAccess                          dstAccess       (dstImage->getAccess());
 +
 +      for (int y = 0; y < height; y++)
 +      for (int x = 0; x < width; x++)
 +      {
 +              const float             depth   = srcImage.getPixDepth(x, y);
 +              const tcu::Vec4 color   = tcu::Vec4(depth, depth, depth, 1.0f);
 +
 +              dstAccess.setPixel(color, x, y);
 +      }
 +
 +      return dstImage;
 +}
 +
 +static MovePtr<tcu::TextureLevel> convertStencilToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat)
 +{
 +      const int                                                       maxValue        (4);
 +      const tcu::ConstPixelBufferAccess       srcImage        (dataFormat, width, height, 1u, data);
 +      MovePtr<tcu::TextureLevel>                      dstImage        (new tcu::TextureLevel(targetFormat, width, height, 1u));
 +      tcu::PixelBufferAccess                          dstAccess       (dstImage->getAccess());
 +
 +      for (int y = 0; y < height; y++)
 +      for (int x = 0; x < width; x++)
 +      {
 +              const int               stencilInt      = srcImage.getPixStencil(x, y);
 +              const float             stencil         = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f;
 +              const tcu::Vec4 color           = tcu::Vec4(stencil, stencil, stencil, 1.0f);
 +
 +              dstAccess.setPixel(color, x, y);
 +      }
 +
 +      return dstImage;
 +}
 +
 +class ColorImagelessTestInstance : public TestInstance
 +{
 +public:
 +                                                                              ColorImagelessTestInstance                      (Context& context, const TestParameters& parameters);
 +protected:
 +      virtual tcu::TestStatus                         iterate                                                         (void);
 +
 +      virtual std::vector<float>                      getVertices                                                     (void);
 +      void                                                            readOneSampleFromMultisampleImage       (const VkFormat                                 srcFormat,
 +                                                                                                                                                       const Unique<VkImage>&                 srcImage,
 +                                                                                                                                                       const deUint32                                 sampleID,
 +                                                                                                                                                       const VkFormat                                 dstFormat,
 +                                                                                                                                                       const Unique<VkImage>&                 dstImage,
 +                                                                                                                                                       const Unique<VkBuffer>&                dstBuffer,
 +                                                                                                                                                       const AspectFlags                              aspect);
 +      virtual MovePtr<tcu::TextureLevel>      generateReferenceImage                          (const tcu::TextureFormat&              textureFormat,
 +                                                                                                                                                       const AspectFlags                              aspectFlags,
 +                                                                                                                                                       const deUint32                                 sample,
 +                                                                                                                                                       const deUint32                                 subpass);
 +      virtual bool                                            verifyBuffer                                            (const UniquePtr<Allocation>&   bufAlloc,
 +                                                                                                                                                       const VkFormat                                 bufferFormat,
 +                                                                                                                                                       const std::string&                             name,
 +                                                                                                                                                       const AspectFlags                              aspectFlags,
 +                                                                                                                                                       const deUint32                                 sample          = NO_SAMPLE,
 +                                                                                                                                                       const deUint32                                 subpass         = NO_SUBPASS);
 +      virtual bool                                            verifyBufferInternal                            (const void*                                    resultData,
 +                                                                                                                                                       const tcu::TextureFormat&              textureFormat,
 +                                                                                                                                                       const tcu::TextureLevel&               referenceImage,
 +                                                                                                                                                       const std::string&                             name);
 +
 +      const bool                                                      m_extensions;
 +      const VkExtent2D                                        m_imageExtent2D;
 +      const TestParameters                            m_parameters;
 +      VkImageUsageFlags                                       m_colorImageUsage;
 +};
 +
 +ColorImagelessTestInstance::ColorImagelessTestInstance (Context& context, const TestParameters& parameters)
 +      : TestInstance                          (context)
 +      , m_extensions                          (context.requireDeviceExtension("VK_KHR_imageless_framebuffer"))
 +      , m_imageExtent2D                       (makeExtent2D(32u, 32u))
 +      , m_parameters                          (parameters)
 +      , m_colorImageUsage                     (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
 +{
 +      const InstanceInterface&                                                                vki                                                             = m_context.getInstanceInterface();
 +      const VkPhysicalDevice                                                                  physDevice                                              = m_context.getPhysicalDevice();
 +      const VkPhysicalDeviceImagelessFramebufferFeaturesKHR&  imagelessFramebufferFeatures    (context.getImagelessFramebufferFeatures());
 +
 +      if (imagelessFramebufferFeatures.imagelessFramebuffer == DE_FALSE)
 +              TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported");
 +
 +      checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
 +}
 +
 +void ColorImagelessTestInstance::readOneSampleFromMultisampleImage (const VkFormat                    srcFormat,
 +                                                                                                                                      const Unique<VkImage>&  srcImage,
 +                                                                                                                                      const deUint32                  sampleID,
 +                                                                                                                                      const VkFormat                  dstFormat,
 +                                                                                                                                      const Unique<VkImage>&  dstImage,
 +                                                                                                                                      const Unique<VkBuffer>& dstBuffer,
 +                                                                                                                                      const AspectFlags               aspect)
 +{
 +      const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
 +      const VkDevice                                          device                          = m_context.getDevice();
 +      const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                           queue                           = m_context.getUniversalQueue();
 +      Allocator&                                                      allocator                       = m_context.getDefaultAllocator();
 +
 +      const tcu::Vec4                                         clearColor                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const bool                                                      color                           = ((aspect & ASPECT_COLOR) != 0);
 +      const bool                                                      depth                           = ((aspect & ASPECT_DEPTH) != 0);
 +      const bool                                                      stencil                         = ((aspect & ASPECT_STENCIL) != 0);
 +      const VkImageAspectFlags                        srcAspect                       = color   ? VK_IMAGE_ASPECT_COLOR_BIT
 +                                                                                                                      : depth   ? VK_IMAGE_ASPECT_DEPTH_BIT
 +                                                                                                                      : VK_IMAGE_ASPECT_STENCIL_BIT;
 +      const VkImageSubresourceRange           srcSubresRange          = makeImageSubresourceRange(srcAspect, 0u, 1u, 0u, 1u);
 +      const Unique<VkImageView>                       srcImageView            (makeImageView                  (vk, device, *srcImage, VK_IMAGE_VIEW_TYPE_2D, srcFormat, srcSubresRange));
 +
 +      const VkImageAspectFlags                        dstAspect                       = VK_IMAGE_ASPECT_COLOR_BIT;
 +      const VkImageSubresourceRange           dstSubresRange          = makeImageSubresourceRange(dstAspect, 0u, 1u, 0u, 1u);
 +      const Unique<VkImageView>                       dstAttachment           (makeImageView                  (vk, device, *dstImage, VK_IMAGE_VIEW_TYPE_2D, dstFormat, dstSubresRange));
 +
 +      const std::string                                       fragModuleInfix         = color   ? "-color"
 +                                                                                                                      : depth   ? "-depth"
 +                                                                                                                      : stencil ? "-stencil"
 +                                                                                                                      : "";
 +      const Unique<VkShaderModule>            vertModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("demultisample-vert"), 0u));
 +      const Unique<VkShaderModule>            fragModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("demultisample" + fragModuleInfix + "-frag"), 0u));
 +      const Unique<VkRenderPass>                      renderPass                      (makeVerifyRenderPass   (vk, device, dstFormat));
 +      const Unique<VkFramebuffer>                     framebuffer                     (makeVerifyFramebuffer  (vk, device, *renderPass, *dstAttachment, m_imageExtent2D));
 +
 +      const VkDescriptorType                          samplerDescType         (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
 +      const Unique<VkSampler>                         sampler                         (makeSampler(vk, device));
 +      const Unique<VkDescriptorSetLayout>     descriptorSetLayout     (DescriptorSetLayoutBuilder()
 +              .addSingleSamplerBinding(samplerDescType, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
 +              .build(vk, device));
 +      const Unique<VkDescriptorPool>          descriptorPool          (DescriptorPoolBuilder()
 +              .addType(samplerDescType)
 +              .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
 +      const Unique<VkDescriptorSet>           descriptorSet           (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
 +      const VkDescriptorImageInfo                     imageDescriptorInfo     (makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
 +
 +      DescriptorSetUpdateBuilder()
 +              .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), samplerDescType, &imageDescriptorInfo)
 +              .update(vk, device);
 +
 +      const Unique<VkPipelineLayout>          pipelineLayout          (makeVerifyPipelineLayout       (vk, device, *descriptorSetLayout));
 +      const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline           (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
 +      const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                      (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer          (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const std::vector<float>                        vertexArray                     (getFullQuadVertices());
 +      const deUint32                                          vertexCount                     (static_cast<deUint32>(vertexArray.size() / 4u));
 +      const VkDeviceSize                                      vertexArraySize         (vertexArray.size() * sizeof(vertexArray[0]));
 +      const Unique<VkBuffer>                          vertexBuffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>                     vertexBufferAlloc       (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                                      vertexBufferOffset      (0u);
 +
 +      fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              if (sampleID == 0)
 +              {
 +                      if (color)
 +                      {
 +                              const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
 +                                                                                                                                                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 +                                                                                                                                                                               *srcImage, srcSubresRange);
 +
 +                              vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      }
 +                      else if (depth)
 +                      {
 +                              const VkImageSubresourceRange   preCopySubresRange      = makeImageSubresourceRange     (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
 +                              const VkImageMemoryBarrier              preCopyBarrier          = makeImageMemoryBarrier        (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
 +                                                                                                                                                                                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 +                                                                                                                                                                                               *srcImage, preCopySubresRange);
 +
 +                              vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      }
 +              }
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor);
 +              {
 +                      vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
 +
 +                      vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
 +
 +                      vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
 +
 +                      vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleID), &sampleID);
 +
 +                      vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *dstImage, dstSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *dstBuffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +}
 +
 +bool ColorImagelessTestInstance::verifyBufferInternal (const void* resultData, const tcu::TextureFormat& textureFormat, const tcu::TextureLevel& referenceImage, const std::string& name)
 +{
 +      const int                                                       dataSize                (m_imageExtent2D.width * m_imageExtent2D.height * textureFormat.getPixelSize());
 +      const tcu::ConstPixelBufferAccess       referenceAccess (referenceImage.getAccess());
 +
 +      if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
 +      {
 +              const tcu::ConstPixelBufferAccess       resultImage     (textureFormat, m_imageExtent2D.width, m_imageExtent2D.height, 1u, resultData);
 +              bool                                                            ok;
 +
 +              ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
 +
 +              return ok;
 +      }
 +
 +      return true;
 +}
 +
 +bool ColorImagelessTestInstance::verifyBuffer (const UniquePtr<Allocation>& bufAlloc, const VkFormat bufferFormat, const std::string& name, const AspectFlags aspectFlags, const deUint32 sample, const deUint32 subpass)
 +{
 +      invalidateMappedMemoryRange(m_context.getDeviceInterface(), m_context.getDevice(), bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
 +
 +      const tcu::TextureFormat                        bufferTextureFormat             (mapVkFormat(bufferFormat));
 +      const bool                                                      multisampled                    (sample != NO_SAMPLE);
 +      const bool                                                      depth                                   ((aspectFlags & ASPECT_DEPTH) != 0);
 +      const bool                                                      stencil                                 ((aspectFlags & ASPECT_STENCIL) != 0);
 +      const bool                                                      convertRequired                 ((depth || stencil) && !multisampled);
 +      const tcu::TextureFormat                        convertTextureFormat    (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNORM_INT8));
 +      const tcu::TextureFormat                        referenceTextureFormat  (convertRequired ? convertTextureFormat : bufferTextureFormat);
 +      const MovePtr<tcu::TextureLevel>        referenceImage                  (generateReferenceImage(referenceTextureFormat, aspectFlags, sample, subpass));
 +
 +      if (!multisampled && depth)
 +      {
 +              MovePtr<tcu::TextureLevel>      convertedImage  (convertDepthToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
 +              tcu::ConstPixelBufferAccess     convertedAccess (convertedImage->getAccess());
 +
 +              return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
 +      }
 +      else if (!multisampled && stencil)
 +      {
 +              MovePtr<tcu::TextureLevel>      convertedImage  (convertStencilToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat));
 +              tcu::ConstPixelBufferAccess     convertedAccess (convertedImage->getAccess());
 +
 +              return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
 +      }
 +      else
 +      {
 +              const void*     resultData      (bufAlloc->getHostPtr());
 +
 +              return verifyBufferInternal(resultData, bufferTextureFormat, *referenceImage, name);
 +      }
 +}
 +
 +MovePtr<tcu::TextureLevel> ColorImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                                         const AspectFlags                    aspectFlags,
 +                                                                                                                                                         const deUint32                               sample,
 +                                                                                                                                                         const deUint32                               subpass)
 +{
 +      const int                                       width                   = m_imageExtent2D.width;
 +      const int                                       height                  = m_imageExtent2D.height;
 +      const int                                       componentValue  (static_cast<int>(0.75f * 0x100));
 +      const tcu::RGBA                         colorDrawRGBA   (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
 +      const tcu::Vec4                         colorDraw               (colorDrawRGBA.toVec());
 +      const tcu::Vec4                         colorFill               (tcu::RGBA::black().toVec());
 +      MovePtr<tcu::TextureLevel>      image                   (new tcu::TextureLevel(textureFormat, width, height));
 +      tcu::PixelBufferAccess          access                  (image->getAccess());
 +
 +      DE_UNREF(aspectFlags);
 +      DE_ASSERT(aspectFlags == ASPECT_COLOR);
 +      DE_UNREF(sample);
 +      DE_ASSERT(sample == NO_SAMPLE);
 +      DE_UNREF(subpass);
 +      DE_ASSERT(subpass == NO_SUBPASS);
 +
 +      for (int y = 0; y < height; ++y)
 +      {
 +              const tcu::Vec4&        validColor      = (y < height / 2) ? colorFill : colorDraw;
 +
 +              for (int x = 0; x < width; ++x)
 +                      access.setPixel(validColor, x, y);
 +      }
 +
 +      return image;
 +}
 +
 +std::vector<float> ColorImagelessTestInstance::getVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f,  0.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f,  0.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f,  0.0f, 0.0f, 1.0f,
 +              +1.0f, +1.0f, 0.0f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +tcu::TestStatus ColorImagelessTestInstance::iterate (void)
 +{
 +      const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
 +      const VkDevice                                  device                          = m_context.getDevice();
 +      const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                   queue                           = m_context.getUniversalQueue();
 +      Allocator&                                              allocator                       = m_context.getDefaultAllocator();
 +
 +      const tcu::Vec4                                 clearColor                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const VkFormat                                  colorFormat                     = m_parameters.colorFormat;
 +      const VkDeviceSize                              colorBufferSize         = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
 +      const VkImageSubresourceRange   colorSubresRange        = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
 +
 +      const Unique<VkImage>                   colorImage                      (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +      const UniquePtr<Allocation>             colorImageAlloc         (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorAttachment         (makeImageView                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                  colorBuffer                     (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             colorBufferAlloc        (bindBuffer                             (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
 +
 +      const Unique<VkShaderModule>    vertModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
 +      const Unique<VkShaderModule>    fragModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
 +      const Unique<VkRenderPass>              renderPass                      (makeRenderPass                 (vk, device, colorFormat, m_parameters.dsFormat));
 +      const Unique<VkFramebuffer>             framebuffer                     (makeFramebuffer                (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat));
 +      const Unique<VkPipelineLayout>  pipelineLayout          (makePipelineLayout             (vk, device));
 +      const Unique<VkPipeline>                pipeline                        (makeGraphicsPipeline   (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
 +      const Unique<VkCommandPool>             cmdPool                         (createCommandPool              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const std::vector<float>                vertexArray                     (getVertices());
 +      const deUint32                                  vertexCount                     (static_cast<deUint32>(vertexArray.size() / 4u));
 +      const VkDeviceSize                              vertexArraySize         (vertexArray.size() * sizeof(vertexArray[0]));
 +      const Unique<VkBuffer>                  vertexBuffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>             vertexBufferAlloc       (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                              vertexBufferOffset      (0u);
 +
 +      fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              const VkRenderPassAttachmentBeginInfoKHR        renderPassAttachmentBeginInfo   =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      1u,                                                                                                                     //  deUint32                    attachmentCount;
 +                      &*colorAttachment                                                                                       //  const VkImageView*  pAttachments;
 +              };
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
 +              {
 +                      vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
 +
 +                      vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
 +
 +                      vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Color image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *colorImage, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +
 +      if (verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
 +              return tcu::TestStatus::pass("Pass");
 +      else
 +              return tcu::TestStatus::fail("Fail");
 +}
 +
 +class DepthImagelessTestInstance : public ColorImagelessTestInstance
 +{
 +public:
 +                                                                              DepthImagelessTestInstance      (Context& context, const TestParameters& parameters);
 +
 +protected:
 +      virtual tcu::TestStatus                         iterate                                         (void);
 +
 +      virtual std::vector<float>                      getVertices                                     (void);
 +
 +      virtual MovePtr<tcu::TextureLevel>      generateReferenceImage          (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                       const AspectFlags                      aspectFlags,
 +                                                                                                                                       const deUint32                         sample,
 +                                                                                                                                       const deUint32                         subpass);
 +
 +      VkImageUsageFlags                                       m_dsImageUsage;
 +};
 +
 +DepthImagelessTestInstance::DepthImagelessTestInstance (Context& context, const TestParameters& parameters)
 +      : ColorImagelessTestInstance    (context, parameters)
 +      , m_dsImageUsage                                (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
 +{
 +      const InstanceInterface&        vki                     = m_context.getInstanceInterface();
 +      const VkPhysicalDevice          physDevice      = m_context.getPhysicalDevice();
 +
 +      checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
 +}
 +
 +MovePtr<tcu::TextureLevel> DepthImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                                         const AspectFlags                    aspectFlags,
 +                                                                                                                                                         const deUint32                               sample,
 +                                                                                                                                                         const deUint32                               subpass)
 +{
 +      const bool                                      color   = ((aspectFlags & ASPECT_COLOR) != 0);
 +      const bool                                      depth   = ((aspectFlags & ASPECT_DEPTH) != 0);
 +      const bool                                      stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
 +      const int                                       width   = m_imageExtent2D.width;
 +      const int                                       height  = m_imageExtent2D.height;
 +      MovePtr<tcu::TextureLevel>      image   (new tcu::TextureLevel(textureFormat, width, height));
 +      tcu::PixelBufferAccess          access  (image->getAccess());
 +
 +      DE_ASSERT(dePop32(aspectFlags) == 1);
 +      DE_UNREF(sample);
 +      DE_ASSERT(sample == NO_SAMPLE);
 +      DE_UNREF(subpass);
 +      DE_ASSERT(subpass == NO_SUBPASS);
 +
 +      if (color)
 +      {
 +              const int               componentValue  (static_cast<int>(0.75f * 0x100));
 +              const tcu::RGBA colorDrawRGBA   (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
 +              const tcu::Vec4 colorDraw               (colorDrawRGBA.toVec());
 +              const tcu::Vec4 colorDrawTop    (tcu::RGBA::white().toVec());
 +              const tcu::Vec4 colorFill               (tcu::RGBA::black().toVec());
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const tcu::Vec4&        validColor      = (y < height / 2) ? colorFill
 +                                                                                      : (x < width  / 2) ? colorDraw
 +                                                                                      : colorDrawTop;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      if (depth)
 +      {
 +              const int                       colorFillValue  (static_cast<int>(1.00f * 0x100));
 +              const int                       colorDrawValue  (static_cast<int>(0.50f * 0x100));
 +              const int                       colorTopValue   (static_cast<int>(0.25f * 0x100));
 +              const tcu::IVec4        colorFill               (colorFillValue, 0, 0, 0xFF);
 +              const tcu::IVec4        colorDraw               (colorDrawValue, 0, 0, 0xFF);
 +              const tcu::IVec4        colorTop                (colorTopValue,  0, 0, 0xFF);
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const tcu::IVec4&       validColor      = (y < height / 2) ? colorFill
 +                                                                                      : (x < width  / 2) ? colorDraw
 +                                                                                      : colorTop;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      if (stencil)
 +      {
 +              const int                       colorFillValue  (static_cast<int>(0.00f * 0x100));
 +              const int                       colorDrawValue  (static_cast<int>(0.25f * 0x100));
 +              const int                       colorTopValue   (static_cast<int>(0.50f * 0x100));
 +              const tcu::IVec4        colorFill               (colorFillValue, 0, 0, 0xFF);
 +              const tcu::IVec4        colorDraw               (colorDrawValue, 0, 0, 0xFF);
 +              const tcu::IVec4        colorTop                (colorTopValue,  0, 0, 0xFF);
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const tcu::IVec4&       validColor      = (y < height / 2) ? colorFill
 +                                                                                      : (x < width  / 2) ? colorDraw
 +                                                                                      : colorTop;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      return image;
 +}
 +
 +std::vector<float> DepthImagelessTestInstance::getVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f,  0.0f, 0.50f, 1.0f,
 +              -1.0f, +1.0f, 0.50f, 1.0f,
 +              +1.0f,  0.0f, 0.50f, 1.0f,
 +              -1.0f, +1.0f, 0.50f, 1.0f,
 +              +1.0f,  0.0f, 0.50f, 1.0f,
 +              +1.0f, +1.0f, 0.50f, 1.0f,
 +
 +               0.0f,  0.0f, 0.25f, 1.0f,
 +               0.0f, +1.0f, 0.25f, 1.0f,
 +              +1.0f,  0.0f, 0.25f, 1.0f,
 +               0.0f, +1.0f, 0.25f, 1.0f,
 +              +1.0f,  0.0f, 0.25f, 1.0f,
 +              +1.0f, +1.0f, 0.25f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +tcu::TestStatus DepthImagelessTestInstance::iterate (void)
 +{
 +      const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
 +      const VkDevice                                  device                          = m_context.getDevice();
 +      const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                   queue                           = m_context.getUniversalQueue();
 +      Allocator&                                              allocator                       = m_context.getDefaultAllocator();
 +
 +      const tcu::Vec4                                 clearColor                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const VkFormat                                  colorFormat                     = m_parameters.colorFormat;
 +      const VkDeviceSize                              colorBufferSize         = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
 +      const VkImageSubresourceRange   colorSubresRange        = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
 +
 +      const Unique<VkImage>                   colorImage                      (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +      const UniquePtr<Allocation>             colorImageAlloc         (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorAttachment         (makeImageView                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                  colorBuffer                     (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             colorBufferAlloc        (bindBuffer                             (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
 +
 +      const float                                             clearDepth                      = 1.0f;
 +      const deUint32                                  clearStencil            = 0u;
 +      const VkFormat                                  dsFormat                        = m_parameters.dsFormat;
 +      const deUint32                                  dsImagePixelSize        = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
 +      const VkImageAspectFlags                dsAspectFlags           = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
 +      const VkImageSubresourceRange   dsSubresRange           = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
 +
 +      const VkDeviceSize                              depthBufferSize         = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
 +      const VkFormat                                  stencilBufferFormat     = getStencilBufferFormat(dsFormat);
 +      const deUint32                                  stencilPixelSize        = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
 +      const VkDeviceSize                              stencilBufferSize       = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
 +
 +      const Unique<VkImage>                   dsImage                         (makeImage                              (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
 +      const UniquePtr<Allocation>             dsImageAlloc            (bindImage                              (vk, device, allocator, *dsImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               dsAttachment            (makeImageView                  (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
 +      const Unique<VkBuffer>                  depthBuffer                     (makeBuffer                             (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             depthBufferAlloc        (bindBuffer                             (vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible));
 +      const Unique<VkBuffer>                  stencilBuffer           (makeBuffer                             (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             stencilBufferAlloc      (bindBuffer                             (vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible));
 +
 +      const Unique<VkShaderModule>    vertModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
 +      const Unique<VkShaderModule>    fragModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
 +      const Unique<VkRenderPass>              renderPass                      (makeRenderPass                 (vk, device, colorFormat, dsFormat));
 +      const Unique<VkFramebuffer>             framebuffer                     (makeFramebuffer                (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, dsFormat, m_dsImageUsage));
 +      const Unique<VkPipelineLayout>  pipelineLayout          (makePipelineLayout             (vk, device));
 +      const Unique<VkPipeline>                pipeline                        (makeGraphicsPipeline   (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL));
 +      const Unique<VkCommandPool>             cmdPool                         (createCommandPool              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const std::vector<float>                vertexArray                     (getVertices());
 +      const deUint32                                  vertexCount                     (static_cast<deUint32>(vertexArray.size() / 4u));
 +      const VkDeviceSize                              vertexArraySize         (vertexArray.size() * sizeof(vertexArray[0]));
 +      const Unique<VkBuffer>                  vertexBuffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>             vertexBufferAlloc       (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                              vertexBufferOffset      (0u);
 +
 +      fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              const VkImageView                                                       attachments[]                                   = { *colorAttachment, *dsAttachment };
 +              const VkRenderPassAttachmentBeginInfoKHR        renderPassAttachmentBeginInfo   =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      DE_LENGTH_OF_ARRAY(attachments),                                                        //  deUint32                    attachmentCount;
 +                      attachments                                                                                                     //  const VkImageView*  pAttachments;
 +              };
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
 +              {
 +                      vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
 +
 +                      vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
 +
 +                      vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Color image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *colorImage, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +
 +              // Depth/Stencil image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier          = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                              VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange);
 +                      const VkBufferImageCopy         depthCopyRegion         = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
 +                      const VkBufferImageCopy         stencilCopyRegion       = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarriers[]      =
 +                      {
 +                              makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE),
 +                              makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE),
 +                      };
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +
 +      {
 +              std::string result;
 +
 +              if (!verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
 +                      result += " Color";
 +
 +              if (!verifyBuffer(depthBufferAlloc, dsFormat, "Depth", ASPECT_DEPTH))
 +                      result += " Depth";
 +
 +              if (!verifyBuffer(stencilBufferAlloc, stencilBufferFormat, "Stencil", ASPECT_STENCIL))
 +                      result += " Stencil";
 +
 +              if (result.empty())
 +                      return tcu::TestStatus::pass("Pass");
 +              else
 +                      return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
 +      }
 +}
 +
 +class ColorResolveImagelessTestInstance : public ColorImagelessTestInstance
 +{
 +public:
 +                                                                              ColorResolveImagelessTestInstance       (Context& context, const TestParameters& parameters);
 +protected:
 +      virtual tcu::TestStatus                         iterate                                                         (void);
 +
 +      virtual MovePtr<tcu::TextureLevel>      generateReferenceImage                          (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                                       const AspectFlags                      aspectFlags,
 +                                                                                                                                                       const deUint32                         sample,
 +                                                                                                                                                       const deUint32                         subpass);
 +
 +      virtual std::vector<float>                      getVertices                                                     (void);
 +};
 +
 +ColorResolveImagelessTestInstance::ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
 +      : ColorImagelessTestInstance    (context, parameters)
 +{
 +      const InstanceInterface&        vki                     = m_context.getInstanceInterface();
 +      const VkPhysicalDevice          physDevice      = m_context.getPhysicalDevice();
 +
 +      // To validate per-sample image image must also be sampled
 +      m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
 +
 +      checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
 +}
 +
 +MovePtr<tcu::TextureLevel> ColorResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&       textureFormat,
 +                                                                                                                                                                        const AspectFlags                     aspectFlags,
 +                                                                                                                                                                        const deUint32                        sample,
 +                                                                                                                                                                        const deUint32                        subpass)
 +{
 +      const int                                       width                   = m_imageExtent2D.width;
 +      const int                                       height                  = m_imageExtent2D.height;
 +      MovePtr<tcu::TextureLevel>      image                   (new tcu::TextureLevel(textureFormat, width, height));
 +      tcu::PixelBufferAccess          access                  (image->getAccess());
 +      const int                                       componentValue  (static_cast<int>(0.75f * 0x100));
 +      const tcu::RGBA                         colorDrawRGBA   (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
 +      const tcu::Vec4                         colorDraw               (colorDrawRGBA.toVec());
 +      const tcu::Vec4                         colorFill               (tcu::RGBA::black().toVec());
 +      const tcu::Vec4                         colorEdge0              (colorFill);
 +      const tcu::Vec4                         colorEdge1              (colorDraw);
 +      const tcu::Vec4                         colorEdgeR              ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w());
 +      const tcu::Vec4&                        colorEdge               = sample == 0 ? colorEdge0
 +                                                                                              : sample == 1 ? colorEdge1
 +                                                                                              : colorEdgeR;
 +
 +      DE_UNREF(aspectFlags);
 +      DE_ASSERT(dePop32(aspectFlags) == 1);
 +      DE_ASSERT(aspectFlags == ASPECT_COLOR);
 +      DE_UNREF(subpass);
 +      DE_ASSERT(subpass == NO_SUBPASS);
 +
 +      for (int y = 0; y < height; ++y)
 +      for (int x = 0; x < width; ++x)
 +      {
 +              const int                       mx                      = width - 1 - x;
 +              const tcu::Vec4&        validColor      = (y == mx) ? colorEdge
 +                                                                              : (y >  mx) ? colorFill
 +                                                                              : colorDraw;
 +
 +              access.setPixel(validColor, x, y);
 +      }
 +
 +      return image;
 +}
 +
 +std::vector<float> ColorResolveImagelessTestInstance::getVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f, -1.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f, -1.0f, 0.0f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +tcu::TestStatus ColorResolveImagelessTestInstance::iterate (void)
 +{
 +      const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
 +      const VkDevice                                  device                                  = m_context.getDevice();
 +      const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                   queue                                   = m_context.getUniversalQueue();
 +      Allocator&                                              allocator                               = m_context.getDefaultAllocator();
 +
 +      const VkSampleCountFlagBits             sampleCount                             = VK_SAMPLE_COUNT_2_BIT;
 +      const tcu::Vec4                                 clearColor                              = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const VkFormat                                  colorFormat                             = m_parameters.colorFormat;
 +      const VkDeviceSize                              colorBufferSize                 = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
 +      const VkImageSubresourceRange   colorSubresRange                = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
 +
 +      const Unique<VkImage>                   colorImage                              (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCount)));
 +      const UniquePtr<Allocation>             colorImageAlloc                 (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorAttachment                 (makeImageView                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +
 +      const Unique<VkImage>                   colorResolveImage               (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +      const UniquePtr<Allocation>             colorResolveImageAlloc  (bindImage                              (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorResolveAttachment  (makeImageView                  (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                  colorResolveBuffer              (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             colorResolveBufferAlloc (bindBuffer                             (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
 +
 +      const Unique<VkShaderModule>    vertModule                              (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
 +      const Unique<VkShaderModule>    fragModule                              (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
 +      const Unique<VkRenderPass>              renderPass                              (makeRenderPass                 (vk, device, colorFormat, m_parameters.dsFormat, sampleCount));
 +      const Unique<VkFramebuffer>             framebuffer                             (makeFramebuffer                (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat, 0u, ASPECT_COLOR));
 +      const Unique<VkPipelineLayout>  pipelineLayout                  (makePipelineLayout             (vk, device));
 +      const Unique<VkPipeline>                pipeline                                (makeGraphicsPipeline   (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_NONE, sampleCount));
 +      const Unique<VkCommandPool>             cmdPool                                 (createCommandPool              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>   cmdBuffer                               (allocateCommandBuffer  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const std::vector<float>                vertexArray                             (getVertices());
 +      const deUint32                                  vertexCount                             (static_cast<deUint32>(vertexArray.size() / 4u));
 +      const VkDeviceSize                              vertexArraySize                 (vertexArray.size() * sizeof(vertexArray[0]));
 +      const Unique<VkBuffer>                  vertexBuffer                    (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>             vertexBufferAlloc               (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                              vertexBufferOffset              (0u);
 +
 +      fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              const VkImageView                                                       attachments[]                                   = { *colorAttachment, *colorResolveAttachment };
 +              const VkRenderPassAttachmentBeginInfoKHR        renderPassAttachmentBeginInfo   =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      DE_LENGTH_OF_ARRAY(attachments),                                                        //  deUint32                    attachmentCount;
 +                      attachments                                                                                                     //  const VkImageView*  pAttachments;
 +              };
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
 +              {
 +                      vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
 +
 +                      vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
 +
 +                      vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Color image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *colorResolveImage, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +
 +      {
 +              std::string result;
 +
 +              if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
 +                      result += " ResolveColor";
 +
 +              // Parse color aspect of separate samples of multisample image
 +              for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
 +              {
 +                      const std::string                               name                            ("Color" + de::toString(sampleNdx));
 +                      const Unique<VkImage>                   imageSample                     (makeImage      (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +                      const UniquePtr<Allocation>             imageSampleAlloc        (bindImage      (vk, device, allocator, *imageSample, MemoryRequirement::Any));
 +                      const Unique<VkBuffer>                  imageBuffer                     (makeBuffer     (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +                      const UniquePtr<Allocation>             imageBufferAlloc        (bindBuffer     (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
 +
 +                      readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);
 +
 +                      if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
 +                              result += " " + name;
 +              }
 +
 +
 +              if (result.empty())
 +                      return tcu::TestStatus::pass("Pass");
 +              else
 +                      return tcu::TestStatus::fail("Fail");
 +      }
 +}
 +
 +class DepthResolveImagelessTestInstance : public DepthImagelessTestInstance
 +{
 +public:
 +                                                                              DepthResolveImagelessTestInstance       (Context& context, const TestParameters& parameters);
 +
 +protected:
 +      virtual tcu::TestStatus                         iterate                                                         (void);
 +
 +      virtual MovePtr<tcu::TextureLevel>      generateReferenceImage                          (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                                       const AspectFlags                      aspectFlags,
 +                                                                                                                                                       const deUint32                         sample,
 +                                                                                                                                                       const deUint32                         subpass);
 +
 +      virtual std::vector<float>                      getVertices                                                     (void);
 +};
 +
 +DepthResolveImagelessTestInstance::DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters)
 +      : DepthImagelessTestInstance    (context, parameters)
 +{
 +      context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");
 +
 +      const InstanceInterface&                                                        vki                                     = m_context.getInstanceInterface();
 +      const VkPhysicalDevice                                                          physDevice                      = m_context.getPhysicalDevice();
 +      VkPhysicalDeviceProperties2                                                     deviceProperties;
 +      VkPhysicalDeviceDepthStencilResolvePropertiesKHR        dsResolveProperties;
 +
 +      deMemset(&deviceProperties, 0, sizeof(deviceProperties));
 +      deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties));
 +
 +      deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
 +      deviceProperties.pNext = &dsResolveProperties;
 +
 +      dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
 +      dsResolveProperties.pNext = DE_NULL;
 +
 +      vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties);
 +
 +      if ((dsResolveProperties.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) == 0)
 +              TCU_THROW(NotSupportedError, "Depth resolve does not support required VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
 +
 +      if ((dsResolveProperties.supportedStencilResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) == 0)
 +              TCU_THROW(NotSupportedError, "Stencil resolve does not support required VK_RESOLVE_MODE_MAX_BIT_KHR");
 +
 +      m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
 +
 +      checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
 +
 +      m_dsImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
 +
 +      checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
 +}
 +
 +MovePtr<tcu::TextureLevel> DepthResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat&       textureFormat,
 +                                                                                                                                                                        const AspectFlags                     aspectFlags,
 +                                                                                                                                                                        const deUint32                        sample,
 +                                                                                                                                                                        const deUint32                        subpass)
 +{
 +      const bool                                      color   = ((aspectFlags & ASPECT_COLOR) != 0);
 +      const bool                                      depth   = ((aspectFlags & ASPECT_DEPTH) != 0);
 +      const bool                                      stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
 +      const int                                       width   = m_imageExtent2D.width;
 +      const int                                       height  = m_imageExtent2D.height;
 +      MovePtr<tcu::TextureLevel>      image   (new tcu::TextureLevel(textureFormat, width, height));
 +      tcu::PixelBufferAccess          access  (image->getAccess());
 +
 +      DE_ASSERT(dePop32(aspectFlags) == 1);
 +      DE_UNREF(subpass);
 +
 +      if (color)
 +      {
 +              const tcu::Vec4         colorDraw       (tcu::RGBA::blue().toVec());
 +              const tcu::Vec4         colorFill       (tcu::RGBA::black().toVec());
 +              const tcu::Vec4         colorEdge0      (colorFill);
 +              const tcu::Vec4         colorEdge1      (colorDraw);
 +              const tcu::Vec4         colorEdgeR      ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w());
 +              const tcu::Vec4&        colorEdge       = sample == 0 ? colorEdge0
 +                                                                              : sample == 1 ? colorEdge1
 +                                                                              : colorEdgeR;
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const int                       mx                      = width - 1 - x;
 +                      const tcu::Vec4&        validColor      = (y == mx) ? colorEdge
 +                                                                                      : (y >  mx) ? colorFill
 +                                                                                      : colorDraw;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      if (depth)
 +      {
 +              const int                       colorFillValue  (static_cast<int>(1.00f * 0x100));
 +              const int                       colorDrawValue  (static_cast<int>(0.00f * 0x100));
 +              const int                       colorEdgeValue  (static_cast<int>(0.50f * 0x100));
 +              const tcu::IVec4        colorFill               (colorFillValue, colorFillValue, colorFillValue, 0xFF);
 +              const tcu::IVec4        colorDraw               (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
 +              const tcu::IVec4        colorEdge0              (colorFill);
 +              const tcu::IVec4        colorEdge1              (colorDraw);
 +              const tcu::IVec4        colorEdgeR              (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF);
 +              const tcu::IVec4&       colorEdge               = sample == 0 ? colorEdge0
 +                                                                                      : sample == 1 ? colorEdge1
 +                                                                                      : colorEdgeR;
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const int                       mx                      = width - 1 - x;
 +                      const tcu::IVec4&       validColor      = (y == mx) ? colorEdge
 +                                                                                      : (y >  mx) ? colorFill
 +                                                                                      : colorDraw;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      if (stencil)
 +      {
 +              const int                       colorFillValue  ((0 * 0x100) / 4);
 +              const int                       colorDrawValue  ((1 * 0x100) / 4);
 +              const int                       colorEdgeValue  ((1 * 0x100) / 4);
 +              const tcu::IVec4        colorFill               (colorFillValue, colorFillValue, colorFillValue, 0xFF);
 +              const tcu::IVec4        colorDraw               (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
 +              const tcu::IVec4        colorEdge0              (colorFill);
 +              const tcu::IVec4        colorEdge1              (colorDraw);
 +              const tcu::IVec4        colorEdgeR              (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF);
 +              const tcu::IVec4&       colorEdge               = sample == 0 ? colorEdge0
 +                                                                                      : sample == 1 ? colorEdge1
 +                                                                                      : colorEdgeR;
 +
 +              for (int y = 0; y < height; ++y)
 +              for (int x = 0; x < width; ++x)
 +              {
 +                      const int                       mx                      = width - 1 - x;
 +                      const tcu::IVec4&       validColor      = (y == mx) ? colorEdge
 +                                                                                      : (y >  mx) ? colorFill
 +                                                                                      : colorDraw;
 +
 +                      access.setPixel(validColor, x, y);
 +              }
 +      }
 +
 +      return image;
 +}
 +
 +std::vector<float> DepthResolveImagelessTestInstance::getVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f, -1.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f, -1.0f, 0.0f, 1.0f,
 +              -1.0f, -1.0f, 0.5f, 1.0f,
 +              -1.0f, +1.0f, 0.5f, 1.0f,
 +              +1.0f, -1.0f, 0.5f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +tcu::TestStatus DepthResolveImagelessTestInstance::iterate (void)
 +{
 +      const DeviceInterface&                  vk                                                      = m_context.getDeviceInterface();
 +      const VkDevice                                  device                                          = m_context.getDevice();
 +      const deUint32                                  queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                   queue                                           = m_context.getUniversalQueue();
 +      Allocator&                                              allocator                                       = m_context.getDefaultAllocator();
 +
 +      const deUint32                                  sampleCount                                     = 2u;
 +      const VkSampleCountFlagBits             sampleCountFlag                         = sampleCountBitFromSampleCount(sampleCount);
 +      const tcu::Vec4                                 clearColor                                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const VkFormat                                  colorFormat                                     = m_parameters.colorFormat;
 +      const VkDeviceSize                              colorBufferSize                         = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
 +      const VkImageSubresourceRange   colorSubresRange                        = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
 +
 +      const Unique<VkImage>                   colorImage                                      (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCountFlag)));
 +      const UniquePtr<Allocation>             colorImageAlloc                         (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorAttachment                         (makeImageView                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +
 +      const Unique<VkImage>                   colorResolveImage                       (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +      const UniquePtr<Allocation>             colorResolveImageAlloc          (bindImage                              (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               colorResolveAttachment          (makeImageView                  (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                  colorResolveBuffer                      (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             colorResolveBufferAlloc         (bindBuffer                             (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
 +
 +      const float                                             clearDepth                                      = 1.0f;
 +      const deUint32                                  clearStencil                            = 0u;
 +      const VkFormat                                  dsFormat                                        = m_parameters.dsFormat;
 +      const deUint32                                  dsImagePixelSize                        = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
 +      const VkImageAspectFlags                dsAspectFlags                           = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
 +      const VkImageSubresourceRange   dsSubresRange                           = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
 +
 +      const VkDeviceSize                              depthBufferSize                         = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
 +      const VkFormat                                  stencilBufferFormat                     = getStencilBufferFormat(dsFormat);
 +      const deUint32                                  stencilPixelSize                        = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
 +      const VkDeviceSize                              stencilBufferSize                       = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
 +
 +      const Unique<VkImage>                   dsImage                                         (makeImage                              (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage, sampleCountFlag)));
 +      const UniquePtr<Allocation>             dsImageAlloc                            (bindImage                              (vk, device, allocator, *dsImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               dsAttachment                            (makeImageView                  (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
 +
 +      const Unique<VkImage>                   dsResolveImage                          (makeImage                              (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
 +      const UniquePtr<Allocation>             dsResolveImageAlloc                     (bindImage                              (vk, device, allocator, *dsResolveImage, MemoryRequirement::Any));
 +      const Unique<VkImageView>               dsResolveAttachment                     (makeImageView                  (vk, device, *dsResolveImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
 +      const Unique<VkBuffer>                  depthResolveBuffer                      (makeBuffer                             (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             depthResolveBufferAlloc         (bindBuffer                             (vk, device, allocator, *depthResolveBuffer, MemoryRequirement::HostVisible));
 +      const Unique<VkBuffer>                  stencilResolveBuffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>             stencilResolveBufferAlloc       (bindBuffer                             (vk, device, allocator, *stencilResolveBuffer, MemoryRequirement::HostVisible));
 +
 +      const Unique<VkShaderModule>    vertModule                                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
 +      const Unique<VkShaderModule>    fragModule                                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
 +      const Unique<VkRenderPass>              renderPass                                      (makeRenderPass                 (vk, device, colorFormat, m_parameters.dsFormat, sampleCountFlag, sampleCountFlag));
 +      const Unique<VkFramebuffer>             framebuffer                                     (makeFramebuffer                (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat, m_dsImageUsage, ASPECT_COLOR|ASPECT_DEPTH_STENCIL));
 +      const Unique<VkPipelineLayout>  pipelineLayout                          (makePipelineLayout             (vk, device));
 +      const Unique<VkPipeline>                pipeline                                        (makeGraphicsPipeline   (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL, sampleCountFlag));
 +      const Unique<VkCommandPool>             cmdPool                                         (createCommandPool              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>   cmdBuffer                                       (allocateCommandBuffer  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const std::vector<float>                vertexArray                                     (getVertices());
 +      const deUint32                                  vertexCount                                     (static_cast<deUint32>(vertexArray.size() / 4u));
 +      const VkDeviceSize                              vertexArraySize                         (vertexArray.size() * sizeof(vertexArray[0]));
 +      const Unique<VkBuffer>                  vertexBuffer                            (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>             vertexBufferAlloc                       (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                              vertexBufferOffset                      (0u);
 +
 +      fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              const VkImageView                                                       attachments[]                                   = { *colorAttachment, *dsAttachment, *colorResolveAttachment, *dsResolveAttachment };
 +              const VkRenderPassAttachmentBeginInfoKHR        renderPassAttachmentBeginInfo   =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      DE_LENGTH_OF_ARRAY(attachments),                                                        //  deUint32                    attachmentCount;
 +                      attachments                                                                                                     //  const VkImageView*  pAttachments;
 +              };
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo);
 +              {
 +                      vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
 +
 +                      vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
 +
 +                      vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Color resolve image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *colorResolveImage, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +
 +              // Depth/Stencil resolve image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier          = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *dsResolveImage, dsSubresRange);
 +                      const VkBufferImageCopy         depthCopyRegion         = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
 +                      const VkBufferImageCopy         stencilCopyRegion       = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarriers[]      =
 +                      {
 +                              makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthResolveBuffer, 0ull, VK_WHOLE_SIZE),
 +                              makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilResolveBuffer, 0ull, VK_WHOLE_SIZE),
 +                      };
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthResolveBuffer, 1u, &depthCopyRegion);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilResolveBuffer, 1u, &stencilCopyRegion);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +
 +      {
 +              std::string result;
 +
 +              if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
 +                      result += " ResolveColor";
 +
 +              if (!verifyBuffer(depthResolveBufferAlloc, dsFormat, "ResolveDepth", ASPECT_DEPTH))
 +                      result += " ResolveDepth";
 +
 +              if (!verifyBuffer(stencilResolveBufferAlloc, stencilBufferFormat, "ResolveStencil", ASPECT_STENCIL))
 +                      result += " ResolveStencil";
 +
 +              // Parse color aspect of separate samples of multisample image
 +              for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
 +              {
 +                      const std::string                               name                            ("Color" + de::toString(sampleNdx));
 +                      const Unique<VkImage>                   imageSample                     (makeImage      (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +                      const UniquePtr<Allocation>             imageSampleAlloc        (bindImage      (vk, device, allocator, *imageSample, MemoryRequirement::Any));
 +                      const Unique<VkBuffer>                  imageBuffer                     (makeBuffer     (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +                      const UniquePtr<Allocation>             imageBufferAlloc        (bindBuffer     (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
 +
 +                      readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR);
 +
 +                      if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
 +                              result += " " + name;
 +              }
 +
 +              // Parse depth aspect of separate samples of multisample image
 +              for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
 +              {
 +                      const std::string                               name                            ("Depth" + de::toString(sampleNdx));
 +                      const Unique<VkImage>                   imageSample                     (makeImage      (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +                      const UniquePtr<Allocation>             imageSampleAlloc        (bindImage      (vk, device, allocator, *imageSample, MemoryRequirement::Any));
 +                      const Unique<VkBuffer>                  imageBuffer                     (makeBuffer     (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +                      const UniquePtr<Allocation>             imageBufferAlloc        (bindBuffer     (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
 +
 +                      readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_DEPTH);
 +
 +                      if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_DEPTH, sampleNdx))
 +                              result += " " + name;
 +              }
 +
 +              // Parse stencil aspect of separate samples of multisample image
 +              for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
 +              {
 +                      const std::string                               name                            ("Stencil" + de::toString(sampleNdx));
 +                      const Unique<VkImage>                   imageSample                     (makeImage      (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
 +                      const UniquePtr<Allocation>             imageSampleAlloc        (bindImage      (vk, device, allocator, *imageSample, MemoryRequirement::Any));
 +                      const Unique<VkBuffer>                  imageBuffer                     (makeBuffer     (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +                      const UniquePtr<Allocation>             imageBufferAlloc        (bindBuffer     (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
 +
 +                      readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_STENCIL);
 +
 +                      if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_STENCIL, sampleNdx))
 +                              result += " " + name;
 +              }
 +
 +              if (result.empty())
 +                      return tcu::TestStatus::pass("Pass");
 +              else
 +                      return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
 +      }
 +}
 +
 +class MultisubpassTestInstance : public ColorImagelessTestInstance
 +{
 +public:
 +                                                                              MultisubpassTestInstance        (Context& context, const TestParameters& parameters);
 +
 +protected:
 +      virtual tcu::TestStatus                         iterate                                         (void);
 +
 +      virtual std::vector<float>                      getVertices                                     (void);
 +
 +      virtual MovePtr<tcu::TextureLevel>      generateReferenceImage          (const tcu::TextureFormat&      textureFormat,
 +                                                                                                                                       const AspectFlags                      aspectFlags,
 +                                                                                                                                       const deUint32                         sample,
 +                                                                                                                                       const deUint32                         subpass);
 +};
 +
 +MultisubpassTestInstance::MultisubpassTestInstance (Context& context, const TestParameters& parameters)
 +      : ColorImagelessTestInstance    (context, parameters)
 +{
 +}
 +
 +std::vector<float> MultisubpassTestInstance::getVertices (void)
 +{
 +      const float                                     verticesData[]  =
 +      {
 +              -1.0f,  0.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f,  0.0f, 0.0f, 1.0f,
 +              -1.0f, +1.0f, 0.0f, 1.0f,
 +              +1.0f,  0.0f, 0.0f, 1.0f,
 +              +1.0f, +1.0f, 0.0f, 1.0f,
 +      };
 +      const std::vector<float>        vertices                (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
 +
 +      return vertices;
 +}
 +
 +MovePtr<tcu::TextureLevel> MultisubpassTestInstance::generateReferenceImage (const tcu::TextureFormat&        textureFormat,
 +                                                                                                                                                       const AspectFlags                      aspectFlags,
 +                                                                                                                                                       const deUint32                         sample,
 +                                                                                                                                                       const deUint32                         subpass)
 +{
 +      const int                                       width                   = m_imageExtent2D.width;
 +      const int                                       height                  = m_imageExtent2D.height;
 +      const tcu::Vec4                         colorDraw0              (0.0f, 0.0f, 1.0f, 1.0f);
 +      const tcu::Vec4                         colorFill0              (tcu::RGBA::black().toVec());
 +      const tcu::Vec4                         colorDraw1              (colorDraw0.x(), 1.0f, colorDraw0.z(), 1.0f);
 +      const tcu::Vec4                         colorFill1              (colorFill0.x(), 1.0f, colorFill0.z(), 1.0f);
 +      const tcu::Vec4&                        colorDraw               ((subpass == 0) ? colorDraw0 : colorDraw1);
 +      const tcu::Vec4&                        colorFill               ((subpass == 0) ? colorFill0 : colorFill1);
 +      MovePtr<tcu::TextureLevel>      image                   (new tcu::TextureLevel(textureFormat, width, height));
 +      tcu::PixelBufferAccess          access                  (image->getAccess());
 +
 +      DE_UNREF(aspectFlags);
 +      DE_ASSERT(aspectFlags == ASPECT_COLOR);
 +      DE_UNREF(sample);
 +      DE_ASSERT(sample == NO_SAMPLE);
 +      DE_ASSERT(subpass != NO_SUBPASS);
 +
 +      for (int y = 0; y < height; ++y)
 +      {
 +              const tcu::Vec4&        validColor      = (y < height / 2) ? colorFill : colorDraw;
 +
 +              for (int x = 0; x < width; ++x)
 +                      access.setPixel(validColor, x, y);
 +      }
 +
 +      return image;
 +}
 +
 +tcu::TestStatus MultisubpassTestInstance::iterate (void)
 +{
 +      const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
 +      const VkDevice                                          device                          = m_context.getDevice();
 +      const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
 +      const VkQueue                                           queue                           = m_context.getUniversalQueue();
 +      Allocator&                                                      allocator                       = m_context.getDefaultAllocator();
 +
 +      const tcu::Vec4                                         clearColor                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 +      const VkFormat                                          colorFormat                     = m_parameters.colorFormat;
 +      const VkDeviceSize                                      colorBufferSize         = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
 +      const VkImageSubresourceRange           colorSubresRange        = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
 +
 +      const Unique<VkImage>                           color0Image                     (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
 +      const UniquePtr<Allocation>                     color0ImageAlloc        (bindImage                              (vk, device, allocator, *color0Image, MemoryRequirement::Any));
 +      const Unique<VkImageView>                       color0Attachment        (makeImageView                  (vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                          color0Buffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>                     color0BufferAlloc       (bindBuffer                             (vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible));
 +
 +      const Unique<VkImage>                           color1Image                     (makeImage                              (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
 +      const UniquePtr<Allocation>                     color1ImageAlloc        (bindImage                              (vk, device, allocator, *color1Image, MemoryRequirement::Any));
 +      const Unique<VkImageView>                       color1Attachment        (makeImageView                  (vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
 +      const Unique<VkBuffer>                          color1Buffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
 +      const UniquePtr<Allocation>                     color1BufferAlloc       (bindBuffer                             (vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible));
 +
 +      const VkDescriptorType                          descriptorType          (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
 +      const Unique<VkDescriptorSetLayout>     descriptorSetLayout     (DescriptorSetLayoutBuilder()
 +              .addSingleBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT)
 +              .build(vk, device));
 +      const Unique<VkDescriptorPool>          descriptorPool          (DescriptorPoolBuilder()
 +              .addType(descriptorType)
 +              .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
 +      const Unique<VkDescriptorSet>           descriptorSet           (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
 +      const VkDescriptorImageInfo                     imageDescriptorInfo     (makeDescriptorImageInfo(DE_NULL, *color0Attachment, VK_IMAGE_LAYOUT_GENERAL));
 +
 +      DescriptorSetUpdateBuilder()
 +              .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageDescriptorInfo)
 +              .update(vk, device);
 +
 +      const Unique<VkRenderPass>                      renderPass                      (makeRenderPass                 (vk, device, colorFormat, DE_NULL));
 +      const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, VK_FORMAT_UNDEFINED, 0u, ASPECT_NONE, 1u));
 +      const Unique<VkCommandPool>                     cmdPool                         (createCommandPool              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
 +      const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 +
 +      const Unique<VkShaderModule>            vertModule0                     (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
 +      const Unique<VkShaderModule>            fragModule0                     (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
 +      const Unique<VkPipelineLayout>          pipelineLayout0         (makePipelineLayout             (vk, device));
 +      const Unique<VkPipeline>                        pipeline0                       (makeGraphicsPipeline   (vk, device, *pipelineLayout0, *renderPass, *vertModule0, *fragModule0, m_imageExtent2D));
 +
 +      const Unique<VkShaderModule>            vertModule1                     (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert1"), 0u));
 +      const Unique<VkShaderModule>            fragModule1                     (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag1"), 0u));
 +      const Unique<VkPipelineLayout>          pipelineLayout1         (makePipelineLayout             (vk, device, 1u, &*descriptorSetLayout));
 +      const Unique<VkPipeline>                        pipeline1                       (makeGraphicsPipeline   (vk, device, *pipelineLayout1, *renderPass, *vertModule1, *fragModule1, m_imageExtent2D, 0u, VK_SAMPLE_COUNT_1_BIT, 1u));
 +
 +      const std::vector<float>                        vertex0Array            (getVertices());
 +      const deUint32                                          vertex0Count            (static_cast<deUint32>(vertex0Array.size() / 4u));
 +      const VkDeviceSize                                      vertex0ArraySize        (vertex0Array.size() * sizeof(vertex0Array[0]));
 +      const Unique<VkBuffer>                          vertex0Buffer           (makeBuffer                             (vk, device, makeBufferCreateInfo(vertex0ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>                     vertex0BufferAlloc      (bindBuffer                             (vk, device, allocator, *vertex0Buffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                                      vertex0BufferOffset     (0u);
 +
 +      const std::vector<float>                        vertex1Array            (getFullQuadVertices());
 +      const deUint32                                          vertex1Count            (static_cast<deUint32>(vertex1Array.size() / 4u));
 +      const VkDeviceSize                                      vertex1ArraySize        (vertex1Array.size() * sizeof(vertex1Array[0]));
 +      const Unique<VkBuffer>                          vertex1Buffer           (makeBuffer                             (vk, device, makeBufferCreateInfo(vertex1ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
 +      const UniquePtr<Allocation>                     vertex1BufferAlloc      (bindBuffer                             (vk, device, allocator, *vertex1Buffer, MemoryRequirement::HostVisible));
 +      const VkDeviceSize                                      vertex1BufferOffset     (0u);
 +
 +      fillBuffer(vk, device, *vertex0BufferAlloc, &vertex0Array[0], vertex0ArraySize);
 +      fillBuffer(vk, device, *vertex1BufferAlloc, &vertex1Array[0], vertex1ArraySize);
 +
 +      beginCommandBuffer(vk, *cmdBuffer);
 +      {
 +              const VkImageView                                                       attachments[]                                   = { *color0Attachment, *color1Attachment };
 +              const VkRenderPassAttachmentBeginInfoKHR        renderPassAttachmentBeginInfo   =
 +              {
 +                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR,        //  VkStructureType             sType;
 +                      DE_NULL,                                                                                                        //  const void*                 pNext;
 +                      DE_LENGTH_OF_ARRAY(attachments),                                                        //  deUint32                    attachmentCount;
 +                      &attachments[0]                                                                                         //  const VkImageView*  pAttachments;
 +              };
 +
 +              beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo);
 +              {
 +                      {
 +                              vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline0);
 +
 +                              vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex0Buffer, &vertex0BufferOffset);
 +
 +                              vk.cmdDraw(*cmdBuffer, vertex0Count, 1u, 0u, 0u);
 +                      }
 +
 +                      vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
 +
 +                      {
 +                              vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
 +
 +                              vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex1Buffer, &vertex1BufferOffset);
 +
 +                              vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout1, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
 +
 +                              vk.cmdDraw(*cmdBuffer, vertex1Count, 1u, 0u, 0u);
 +                      }
 +              }
 +              endRenderPass(vk, *cmdBuffer);
 +
 +              // Subpass0 color image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *color0Image, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +
 +              // Subpass1 color image copy
 +              {
 +                      const VkImageMemoryBarrier      preCopyBarrier  = makeImageMemoryBarrier        (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
 +                                                                                                                                                                       VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
 +                                                                                                                                                                       *color1Image, colorSubresRange);
 +                      const VkBufferImageCopy         region                  = makeBufferImageCopy           (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
 +                                                                                                                                                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
 +                      const VkBufferMemoryBarrier     postCopyBarrier = makeBufferMemoryBarrier       (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE);
 +
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
 +                      vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u, &region);
 +                      vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
 +              }
 +      }
 +      endCommandBuffer(vk, *cmdBuffer);
 +      submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 +
 +      {
 +              std::string result;
 +
 +              if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u))
 +                      result += " ColorSubpass0";
 +
 +              if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u))
 +                      result += " ColorSubpass1";
 +
 +              if (result.empty())
 +                      return tcu::TestStatus::pass("Pass");
 +              else
 +                      return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
 +      }
 +}
 +
 +class BaseTestCase : public TestCase
 +{
 +public:
 +                                                      BaseTestCase    (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters);
 +      virtual                                 ~BaseTestCase   (void);
 +
 +protected:
 +      virtual void                    initPrograms    (SourceCollections& programCollection) const;
 +      virtual TestInstance*   createInstance  (Context& context) const;
 +
 +      const TestParameters    m_parameters;
 +};
 +
 +BaseTestCase::BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters)
 +      : TestCase              (context, name, description)
 +      , m_parameters  (parameters)
 +{
 +}
 +
 +BaseTestCase::~BaseTestCase ()
 +{
 +}
 +
 +void BaseTestCase::initPrograms (SourceCollections& programCollection) const
 +{
 +      // Vertex shader
 +      {
 +              std::ostringstream src;
 +
 +              if (m_parameters.testType == TEST_TYPE_COLOR || m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
 +              {
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(location = 0) in highp vec4 a_position;\n"
 +                              << "layout(location = 0) out highp vec4 a_color;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    gl_Position = a_position;\n"
 +                              << "    if (gl_VertexIndex < 6)\n"
 +                              << "        a_color = vec4(0.75f, 0.75f, 0.75f, 1.0f);\n"
 +                              << "    else\n"
 +                              << "        a_color = vec4(1.00f, 1.00f, 1.00f, 1.0f);\n"
 +                              << "}\n";
 +              }
 +
 +              if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
 +              {
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(location = 0) in highp vec4 a_position;\n"
 +                              << "layout(location = 0) out highp vec4 a_color;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    gl_Position = a_position;\n"
 +                              << "    if (gl_VertexIndex < 3)\n"
 +                              << "        a_color = vec4(0.00f, 0.00f, 1.00f, 1.0f);\n"
 +                              << "    else\n"
 +                              << "        a_color = vec4(0.00f, 1.00f, 0.00f, 1.0f);\n"
 +                              << "}\n";
 +              }
 +
 +              if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
 +              {
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(location = 0) in highp vec4 a_position;\n"
 +                              << "layout(location = 0) out highp vec4 a_color;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    gl_Position = a_position;\n"
 +                              << "    a_color = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
 +                              << "}\n";
 +              }
 +
 +              programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
 +      }
 +
 +      // Fragment shader
 +      {
 +              std::ostringstream src;
 +
 +              src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                      << "\n"
 +                      << "layout(location = 0) in highp vec4 a_color;\n"
 +                      << "layout(location = 0) out highp vec4 o_color;\n"
 +                      << "\n"
 +                      << "void main (void)\n"
 +                      << "{\n"
 +                      << "    o_color = a_color;\n"
 +                      << "}\n";
 +
 +              programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
 +      }
 +
 +      // Additional shaders
 +      if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
 +      {
 +              // Vertex shader
 +              {
 +                      std::ostringstream src;
 +
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(location = 0) in highp vec4 a_position;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    gl_Position = a_position;\n"
 +                              << "}\n";
 +
 +                      programCollection.glslSources.add("demultisample-vert") << glu::VertexSource(src.str());
 +              }
 +
 +              // Fragment shader
 +              {
 +                      // Color
 +                      {
 +                              std::ostringstream src;
 +
 +                              src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                                      << "\n"
 +                                      << "layout(set = 0, binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
 +                                      << "layout(push_constant) uniform PushConstantsBlock {\n"
 +                                      << "    highp int sampleID;\n"
 +                                      << "} pushConstants;\n"
 +                                      << "layout(location = 0) out highp vec4 o_color;\n"
 +                                      << "\n"
 +                                      << "void main (void)\n"
 +                                      << "{\n"
 +                                      << "    o_color = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
 +                                      << "}\n";
 +
 +                              programCollection.glslSources.add("demultisample-color-frag") << glu::FragmentSource(src.str());
 +                      }
 +
 +                      // Depth
 +                      {
 +                              std::ostringstream src;
 +
 +                              // Depth-component textures are treated as one-component floating-point textures.
 +                              src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                                      << "\n"
 +                                      << "layout(binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
 +                                      << "layout(push_constant) uniform PushConstantsBlock {\n"
 +                                      << "    highp int sampleID;\n"
 +                                      << "} pushConstants;\n"
 +                                      << "layout(location = 0) out highp vec4 o_color;\n"
 +                                      << "\n"
 +                                      << "void main (void)\n"
 +                                      << "{\n"
 +                                      << "    vec4 val = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
 +                                      << "    o_color = vec4(val.x, val.x, val.x, 1.0);\n"
 +                                      << "}\n";
 +
 +                              programCollection.glslSources.add("demultisample-depth-frag") << glu::FragmentSource(src.str());
 +                      }
 +
 +                      // Stencil
 +                      {
 +                              std::ostringstream src;
 +
 +                              // Stencil-component textures are treated as one-component unsigned integer textures.
 +                              src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                                      << "\n"
 +                                      << "layout(binding = 0) uniform usampler2DMS u_ms_image_sampler;\n"
 +                                      << "layout(push_constant) uniform PushConstantsBlock {\n"
 +                                      << "    highp int sampleID;\n"
 +                                      << "} pushConstants;\n"
 +                                      << "layout(location = 0) out highp vec4 o_color;\n"
 +                                      << "\n"
 +                                      << "void main (void)\n"
 +                                      << "{\n"
 +                                      << "    uvec4 uVal = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
 +                                      << "    float val = float(uVal.x) / 4.0f;\n"
 +                                      << "    o_color = vec4(val, val, val, 1.0);\n"
 +                                      << "}\n";
 +
 +                              programCollection.glslSources.add("demultisample-stencil-frag") << glu::FragmentSource(src.str());
 +                      }
 +              }
 +      }
 +
 +      if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
 +      {
 +              // Vertex shader
 +              {
 +                      std::ostringstream src;
 +
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(location = 0) in highp vec4 a_position;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    gl_Position = a_position;\n"
 +                              << "}\n";
 +
 +                      programCollection.glslSources.add("vert1") << glu::VertexSource(src.str());
 +              }
 +
 +              // Fragment shader
 +              {
 +                      std::ostringstream src;
 +
 +                      src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
 +                              << "\n"
 +                              << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput u_colors;\n"
 +                              << "layout(location = 0) out highp vec4 o_color;\n"
 +                              << "\n"
 +                              << "void main (void)\n"
 +                              << "{\n"
 +                              << "    o_color = subpassLoad(u_colors);\n"
 +                              << "    o_color.g = 1.0f;\n"
 +                              << "    o_color.a = 1.0f;\n"
 +                              << "}\n";
 +
 +                      programCollection.glslSources.add("frag1") << glu::FragmentSource(src.str());
 +              }
 +      }
 +
 +
 +      return;
 +}
 +
 +TestInstance* BaseTestCase::createInstance (Context& context) const
 +{
 +      if (m_parameters.testType == TEST_TYPE_COLOR)
 +              return new ColorImagelessTestInstance(context, m_parameters);
 +
 +      if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
 +              return new DepthImagelessTestInstance(context, m_parameters);
 +
 +      if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE)
 +              return new ColorResolveImagelessTestInstance(context, m_parameters);
 +
 +      if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
 +              return new DepthResolveImagelessTestInstance(context, m_parameters);
 +
 +      if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
 +              return new MultisubpassTestInstance(context, m_parameters);
 +
 +      TCU_THROW(InternalError, "Unknown test type specified");
 +}
 +
 +tcu::TestNode*        imagelessColorTests (tcu::TestContext& testCtx)
 +{
 +      TestParameters  parameters      =
 +      {
 +              TEST_TYPE_COLOR,                                        //  TestType    testType;
 +              VK_FORMAT_R8G8B8A8_UNORM,                       //  VkFormat    colorFormat;
 +              VK_FORMAT_UNDEFINED,                            //  VkFormat    dsFormat;
 +      };
 +
 +      return new BaseTestCase(testCtx, "color", "Imageless color attachment test", parameters);
 +}
 +
 +tcu::TestNode*        imagelessDepthStencilTests (tcu::TestContext& testCtx)
 +{
 +      TestParameters  parameters      =
 +      {
 +              TEST_TYPE_DEPTH_STENCIL,                        //  TestType    testType;
 +              VK_FORMAT_R8G8B8A8_UNORM,                       //  VkFormat    colorFormat;
 +              VK_FORMAT_D24_UNORM_S8_UINT,            //  VkFormat    dsFormat;
 +      };
 +
 +      return new BaseTestCase(testCtx, "depth_stencil", "Imageless depth/stencil attachment test", parameters);
 +}
 +
 +tcu::TestNode*        imagelessColorResolveTests (tcu::TestContext& testCtx)
 +{
 +      TestParameters  parameters      =
 +      {
 +              TEST_TYPE_COLOR_RESOLVE,                        //  TestType    testType;
 +              VK_FORMAT_R8G8B8A8_UNORM,                       //  VkFormat    colorFormat;
 +              VK_FORMAT_UNDEFINED,                            //  VkFormat    dsFormat;
 +      };
 +
 +      return new BaseTestCase(testCtx, "color_resolve", "Imageless color attachment resolve test", parameters);
 +}
 +
 +tcu::TestNode*        imagelessDepthStencilResolveTests (tcu::TestContext& testCtx)
 +{
 +      TestParameters  parameters      =
 +      {
 +              TEST_TYPE_DEPTH_STENCIL_RESOLVE,        //  TestType    testType;
 +              VK_FORMAT_R8G8B8A8_UNORM,                       //  VkFormat    colorFormat;
 +              VK_FORMAT_D24_UNORM_S8_UINT,            //  VkFormat    dsFormat;
 +      };
 +
 +      return new BaseTestCase(testCtx, "depth_stencil_resolve", "Imageless color and depth/stencil attachment resolve test", parameters);
 +}
 +
 +tcu::TestNode*        imagelessMultisubpass (tcu::TestContext& testCtx)
 +{
 +      TestParameters  parameters      =
 +      {
 +              TEST_TYPE_MULTISUBPASS,                 //  TestType    testType;
 +              VK_FORMAT_R8G8B8A8_UNORM,               //  VkFormat    colorFormat;
 +              VK_FORMAT_D24_UNORM_S8_UINT,    //  VkFormat    dsFormat;
 +      };
 +
 +      return new BaseTestCase(testCtx, "multisubpass", "Multi-subpass test", parameters);
 +}
 +
 +}     // anonymous
 +
 +tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
 +{
 +      de::MovePtr<tcu::TestCaseGroup> imagelessFramebufferGroup (new tcu::TestCaseGroup(testCtx, "imageless_framebuffer", "Imageless Framebuffer tests"));
 +
 +      imagelessFramebufferGroup->addChild(imagelessColorTests(testCtx));                                              // Color only test
 +      imagelessFramebufferGroup->addChild(imagelessDepthStencilTests(testCtx));                               // Color and depth/stencil test
 +      imagelessFramebufferGroup->addChild(imagelessColorResolveTests(testCtx));                               // Color and color resolve test
 +      imagelessFramebufferGroup->addChild(imagelessDepthStencilResolveTests(testCtx));                // Color, depth and depth resolve test (interaction with VK_KHR_depth_stencil_resolve)
 +      imagelessFramebufferGroup->addChild(imagelessMultisubpass(testCtx));                                    // Multi-subpass test
 +
 +      return imagelessFramebufferGroup.release();
 +}
 +
 +} // imageless
 +} // vkt