Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
index 7b4644e..6e38fdb 100644 (file)
@@ -32,6 +32,8 @@
 #include "tcuTextureUtil.hpp"
 #include "tcuVectorType.hpp"
 #include "tcuVectorUtil.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTexLookupVerifier.hpp"
 
 #include "vkImageUtil.hpp"
 #include "vkMemUtil.hpp"
 #include "vkRefUtil.hpp"
 #include "vktTestCase.hpp"
 #include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
 #include "vkTypeUtil.hpp"
 
+#include <set>
+
 namespace vkt
 {
 
 namespace api
 {
 
-using namespace vk;
-
 namespace
 {
+enum MirrorMode
+{
+       MIRROR_MODE_NONE = 0,
+       MIRROR_MODE_X = (1<<0),
+       MIRROR_MODE_Y = (1<<1),
+       MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
+
+       MIRROR_MODE_LAST
+};
+
+enum AllocationKind
+{
+       ALLOCATION_KIND_SUBALLOCATED,
+       ALLOCATION_KIND_DEDICATED,
+};
+
+template <typename Type>
+class BinaryCompare
+{
+public:
+       bool operator() (const Type& a, const Type& b) const
+       {
+               return deMemCmp(&a, &b, sizeof(Type)) < 0;
+       }
+};
+
+typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >   FormatSet;
+
+FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
+FormatSet dedicatedAllocationBlittingFormatsToTestSet;
+
+using namespace vk;
 
 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
 {
@@ -84,6 +119,14 @@ union CopyRegion
        VkImageResolve          imageResolve;
 };
 
+struct ImageParms
+{
+       VkImageType             imageType;
+       VkFormat                format;
+       VkExtent3D              extent;
+       VkImageLayout   operationLayout;
+};
+
 struct TestParams
 {
        union Data
@@ -91,22 +134,99 @@ struct TestParams
                struct Buffer
                {
                        VkDeviceSize    size;
-               }       buffer;
-               struct Image
-               {
-                       VkFormat                format;
-                       VkExtent3D              extent;
-               }       image;
-       }       src, dst;
+               } buffer;
+
+               ImageParms      image;
+       } src, dst;
 
        std::vector<CopyRegion> regions;
+
        union
        {
                VkFilter                                filter;
                VkSampleCountFlagBits   samples;
        };
+
+       AllocationKind allocationKind;
 };
 
+de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&       vki,
+                                                                               const DeviceInterface&          vkd,
+                                                                               const VkPhysicalDevice&         physDevice,
+                                                                               const VkDevice                          device,
+                                                                               const VkBuffer&                         buffer,
+                                                                               const MemoryRequirement         requirement,
+                                                                               Allocator&                                      allocator,
+                                                                               AllocationKind                          allocationKind)
+{
+       switch (allocationKind)
+       {
+               case ALLOCATION_KIND_SUBALLOCATED:
+               {
+                       const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
+
+                       return allocator.allocate(memoryRequirements, requirement);
+               }
+
+               case ALLOCATION_KIND_DEDICATED:
+               {
+                       return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
+               }
+
+               default:
+               {
+                       TCU_THROW(InternalError, "Invalid allocation kind");
+               }
+       }
+}
+
+de::MovePtr<Allocation> allocateImage (const InstanceInterface&                vki,
+                                                                          const DeviceInterface&               vkd,
+                                                                          const VkPhysicalDevice&              physDevice,
+                                                                          const VkDevice                               device,
+                                                                          const VkImage&                               image,
+                                                                          const MemoryRequirement              requirement,
+                                                                          Allocator&                                   allocator,
+                                                                          AllocationKind                               allocationKind)
+{
+       switch (allocationKind)
+       {
+               case ALLOCATION_KIND_SUBALLOCATED:
+               {
+                       const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
+
+                       return allocator.allocate(memoryRequirements, requirement);
+               }
+
+               case ALLOCATION_KIND_DEDICATED:
+               {
+                       return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
+               }
+
+               default:
+               {
+                       TCU_THROW(InternalError, "Invalid allocation kind");
+               }
+       }
+}
+
+
+inline deUint32 getArraySize(const ImageParms& parms)
+{
+       return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
+}
+
+inline VkExtent3D getExtent3D(const ImageParms& parms)
+{
+       const VkExtent3D                extent                                  =
+       {
+               parms.extent.width,
+               parms.extent.height,
+               (parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
+       };
+       return extent;
+}
+
 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
 {
        tcu::TextureFormat format;
@@ -160,7 +280,7 @@ protected:
        void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
        virtual void                                            generateExpectedResult                          (void);
        void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
-       void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst);
+       void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms);
        virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
        virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
        deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
@@ -168,15 +288,20 @@ protected:
                                                                                        return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
                                                                                }
 
-       de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                                    image,
-                                                                                                                                                        vk::VkFormat                                   format,
-                                                                                                                                                        const VkExtent3D                               imageSize);
+       de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
+                                                                                                                                                        const ImageParms&                      imageParms);
+       void                                                            submitCommandsAndWait                           (const DeviceInterface&         vk,
+                                                                                                                                                       const VkDevice                          device,
+                                                                                                                                                       const VkQueue                           queue,
+                                                                                                                                                       const VkCommandBuffer&          cmdBuffer);
 
 private:
        void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
-                                                                                                                                                        const VkImage&                                         dst);
+                                                                                                                                                        const VkImage&                                         dst,
+                                                                                                                                                        const ImageParms&                                      parms);
        void                                                            readImageAspect                                         (vk::VkImage                                            src,
-                                                                                                                                                        const tcu::PixelBufferAccess&          dst);
+                                                                                                                                                        const tcu::PixelBufferAccess&          dst,
+                                                                                                                                                        const ImageParms&                                      parms);
 };
 
 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
@@ -187,88 +312,101 @@ CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context,
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
 
-       // Create command pool
+       if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
        {
-               const VkCommandPoolCreateInfo           cmdPoolParams                   =
-               {
-                       VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
-                       DE_NULL,                                                                                // const void*                  pNext;
-                       VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
-                       queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
-               };
+               const std::string extensionName("VK_KHR_dedicated_allocation");
 
-               m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
+               if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
+                       TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
        }
 
-       // Create command buffer
-       {
-               const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
-               {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
-                       DE_NULL,                                                                                // const void*                          pNext;
-                       *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
-                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
-                       1u                                                                                              // deUint32                                     bufferCount;
-               };
+       // Create command pool
+       m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
 
-               m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
-       }
+       // Create command buffer
+       m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
 
        // Create fence
-       {
-               const VkFenceCreateInfo                         fenceParams                             =
-               {
-                       VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
-                       DE_NULL,                                                                // const void*                  pNext;
-                       0u                                                                              // VkFenceCreateFlags   flags;
-               };
-
-               m_fence = createFence(vk, vkDevice, &fenceParams);
-       }
+       m_fence = createFence(vk, vkDevice);
 }
 
 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
 {
+       const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(buffer.getFormat().type);
+       tcu::Vec4                                               maxValue                (1.0f);
+
+       if (buffer.getFormat().order == tcu::TextureFormat::S)
+       {
+               // Stencil-only is stored in the first component. Stencil is always 8 bits.
+               maxValue.x() = 1 << 8;
+       }
+       else if (buffer.getFormat().order == tcu::TextureFormat::DS)
+       {
+               // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
+               maxValue.w() = 1 << 8;
+       }
+       else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
+       {
+               // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
+               const tcu::IVec4        bits    = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
+               const int                       signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
+
+               for (int i = 0; i < 4; ++i)
+               {
+                       if (bits[i] != 0)
+                               maxValue[i] = static_cast<float>((1 << (bits[i] - signBit)) - 1);
+               }
+       }
+
        if (mode == FILL_MODE_GRADIENT)
        {
-               tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
+               tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
                return;
        }
 
-       const tcu::Vec4         redColor        (1.0, 0.0, 0.0, 1.0);
-       const tcu::Vec4         greenColor      (0.0, 1.0, 0.0, 1.0);
-       const tcu::Vec4         blueColor       (0.0, 0.0, 1.0, 1.0);
-       const tcu::Vec4         whiteColor      (1.0, 1.0, 1.0, 1.0);
+       const tcu::Vec4         redColor        (maxValue.x(),  0.0,                    0.0,                    maxValue.w());
+       const tcu::Vec4         greenColor      (0.0,                   maxValue.y(),   0.0,                    maxValue.w());
+       const tcu::Vec4         blueColor       (0.0,                   0.0,                    maxValue.z(),   maxValue.w());
+       const tcu::Vec4         whiteColor      (maxValue.x(),  maxValue.y(),   maxValue.z(),   maxValue.w());
 
-       for (int z = 0; z < depth; z++)
+       for (int z = 0; z < depth;  ++z)
+       for (int y = 0; y < height; ++y)
+       for (int x = 0; x < width;  ++x)
        {
-               for (int y = 0; y < height; y++)
+               switch (mode)
                {
-                       for (int x = 0; x < width; x++)
-                       {
-                               switch (mode)
+                       case FILL_MODE_WHITE:
+                               if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
+                               {
+                                       buffer.setPixDepth(1.0f, x, y, z);
+                                       if (tcu::hasStencilComponent(buffer.getFormat().order))
+                                               buffer.setPixStencil(255, x, y, z);
+                               }
+                               else
+                                       buffer.setPixel(whiteColor, x, y, z);
+                               break;
+
+                       case FILL_MODE_RED:
+                               if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
                                {
-                                       case FILL_MODE_WHITE:
-                                               if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
-                                               {
-                                                       buffer.setPixDepth(1.0f, x, y, z);
-                                                       if (tcu::hasStencilComponent(buffer.getFormat().order))
-                                                               buffer.setPixStencil(255, x, y, z);
-                                               }
-                                               else
-                                                       buffer.setPixel(whiteColor, x, y, z);
-                                               break;
-                                       case FILL_MODE_RED:
-                                               DE_ASSERT(!tcu::isCombinedDepthStencilType(buffer.getFormat().type)); // combined types cannot be accessed directly
-                                               buffer.setPixel(redColor, x, y, z);
-                                               break;
-                                       case FILL_MODE_MULTISAMPLE:
-                                               buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z);
-                                               break;
-                                       default:
-                                               break;
+                                       buffer.setPixDepth(redColor[0], x, y, z);
+                                       if (tcu::hasStencilComponent(buffer.getFormat().order))
+                                               buffer.setPixStencil((int)redColor[3], x, y, z);
                                }
+                               else
+                                       buffer.setPixel(redColor, x, y, z);
+                               break;
+
+                       case FILL_MODE_MULTISAMPLE:
+                       {
+                               float xScaled = static_cast<float>(x) / static_cast<float>(width);
+                               float yScaled = static_cast<float>(y) / static_cast<float>(height);
+                               buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
+                               break;
                        }
+
+                       default:
+                               break;
                }
        }
 }
@@ -284,18 +422,20 @@ void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bu
        flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
 }
 
-void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image)
+void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms)
 {
+       const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
        const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = m_context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = m_context.getDevice();
        const VkQueue                           queue                           = m_context.getUniversalQueue();
        const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
-
        Move<VkBuffer>                          buffer;
        const deUint32                          bufferSize                      = calculateSize(imageAccess);
        de::MovePtr<Allocation>         bufferAlloc;
-       Move<VkCommandBuffer>           cmdBuffer;
+       const deUint32                          arraySize                       = getArraySize(parms);
+       const VkExtent3D                        imageExtent                     = getExtent3D(parms);
 
        // Create source buffer
        {
@@ -312,24 +452,10 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                };
 
                buffer          = createBuffer(vk, vkDevice, &bufferParams);
-               bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
+               bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
        }
 
-       // Create command buffer
-       {
-               const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
-               {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
-                       DE_NULL,                                                                                // const void*                          pNext;
-                       *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
-                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
-                       1u,                                                                                             // deUint32                                     bufferCount;
-               };
-
-               cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
-       }
-
        // Barriers for copying buffer to image
        const VkBufferMemoryBarrier                             preBufferBarrier                =
        {
@@ -344,7 +470,9 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                bufferSize                                                                              // VkDeviceSize         size;
        };
 
-       const VkImageAspectFlags                                aspect                                  = getAspectFlags(imageAccess.getFormat());
+       const VkImageAspectFlags                                formatAspect                    = getAspectFlags(mapVkFormat(parms.format));
+       const bool                                                              skipPreImageBarrier             = formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
+                                                                                                                                         getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT;
        const VkImageMemoryBarrier                              preImageBarrier                 =
        {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
@@ -357,11 +485,11 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
                image,                                                                                  // VkImage                                      image;
                {                                                                                               // VkImageSubresourceRange      subresourceRange;
-                       aspect,                                                                 // VkImageAspectFlags   aspect;
-                       0u,                                                                             // deUint32                             baseMipLevel;
-                       1u,                                                                             // deUint32                             mipLevels;
-                       0u,                                                                             // deUint32                             baseArraySlice;
-                       1u,                                                                             // deUint32                             arraySize;
+                       formatAspect,   // VkImageAspectFlags   aspect;
+                       0u,                             // deUint32                             baseMipLevel;
+                       1u,                             // deUint32                             mipLevels;
+                       0u,                             // deUint32                             baseArraySlice;
+                       arraySize,              // deUint32                             arraySize;
                }
        };
 
@@ -377,15 +505,14 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
                image,                                                                                  // VkImage                                      image;
                {                                                                                               // VkImageSubresourceRange      subresourceRange;
-                       aspect,                                                                 // VkImageAspectFlags   aspect;
-                       0u,                                                                             // deUint32                             baseMipLevel;
-                       1u,                                                                             // deUint32                             mipLevels;
-                       0u,                                                                             // deUint32                             baseArraySlice;
-                       1u,                                                                             // deUint32                             arraySize;
+                       formatAspect,                           // VkImageAspectFlags   aspect;
+                       0u,                                                     // deUint32                             baseMipLevel;
+                       1u,                                                     // deUint32                             mipLevels;
+                       0u,                                                     // deUint32                             baseArraySlice;
+                       arraySize,                                      // deUint32                             arraySize;
                }
        };
 
-       const VkExtent3D                        imageExtent             = { (deUint32)imageAccess.getWidth(), (deUint32)imageAccess.getHeight(), 1u };
        const VkBufferImageCopy         copyRegion              =
        {
                0u,                                                                                             // VkDeviceSize                         bufferOffset;
@@ -395,7 +522,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                        getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
                        0u,                                                                                             // deUint32                             mipLevel;
                        0u,                                                                                             // deUint32                             baseArrayLayer;
-                       1u,                                                                                             // deUint32                             layerCount;
+                       arraySize,                                                                              // deUint32                             layerCount;
                },                                                                                              // VkImageSubresourceLayers     imageSubresource;
                { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
                imageExtent                                                                             // VkExtent3D                           imageExtent;
@@ -414,31 +541,17 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                (const VkCommandBufferInheritanceInfo*)DE_NULL,
        };
 
-       VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
-       vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
-       vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
-       vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
-       VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
-
-       const VkSubmitInfo                                              submitInfo                              =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
+       VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
+                                                 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
+       vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
+       VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
 
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
 }
 
-void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst)
+void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms)
 {
        if (tcu::isCombinedDepthStencilType(src.getFormat().type))
        {
@@ -446,18 +559,18 @@ void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAcce
                {
                        tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
                        tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
-                       uploadImageAspect(depthTexture.getAccess(), dst);
+                       uploadImageAspect(depthTexture.getAccess(), dst, parms);
                }
 
                if (tcu::hasStencilComponent(src.getFormat().order))
                {
                        tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
                        tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
-                       uploadImageAspect(stencilTexture.getAccess(), dst);
+                       uploadImageAspect(stencilTexture.getAccess(), dst, parms);
                }
        }
        else
-               uploadImageAspect(src, dst);
+               uploadImageAspect(src, dst, parms);
 }
 
 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
@@ -467,13 +580,13 @@ tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelB
        if (isFloatFormat(result.getFormat()))
        {
                const tcu::Vec4 threshold (0.0f);
-               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
+               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
                        return tcu::TestStatus::fail("CopiesAndBlitting test");
        }
        else
        {
                const tcu::UVec4 threshold (0u);
-               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
+               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
                        return tcu::TestStatus::fail("CopiesAndBlitting test");
        }
 
@@ -487,6 +600,7 @@ void CopiesAndBlittingTestInstance::generateExpectedResult (void)
 
        m_expectedTextureLevel  = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
        tcu::copy(m_expectedTextureLevel->getAccess(), dst);
+
        for (deUint32 i = 0; i < m_params.regions.size(); i++)
                copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
 }
@@ -504,18 +618,21 @@ public:
 };
 
 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                       image,
-                                                                                                        const tcu::PixelBufferAccess&  dst)
+                                                                                                        const tcu::PixelBufferAccess&  dst,
+                                                                                                        const ImageParms&                              imageParms)
 {
+       const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
        const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
+       const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
        const VkDevice                          device                          = m_context.getDevice();
        const VkQueue                           queue                           = m_context.getUniversalQueue();
        Allocator&                                      allocator                       = m_context.getDefaultAllocator();
 
        Move<VkBuffer>                          buffer;
        de::MovePtr<Allocation>         bufferAlloc;
-       Move<VkCommandBuffer>           cmdBuffer;
        const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
        const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
+       const VkExtent3D                        imageExtent                     = getExtent3D(imageParms);
 
        // Create destination buffer
        {
@@ -532,43 +649,32 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                  image,
                };
 
                buffer          = createBuffer(vk, device, &bufferParams);
-               bufferAlloc     = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
+               bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
-       }
-
-       // Create command pool and buffer
-       {
-               const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
-               {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
-                       DE_NULL,                                                                                // const void*                          pNext;
-                       *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
-                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
-                       1u                                                                                              // deUint32                                     bufferCount;
-               };
 
-               cmdBuffer       = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
+               deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
+               flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
        }
 
        // Barriers for copying image to buffer
-       const VkImageAspectFlags                                aspect                                  = getAspectFlags(dst.getFormat());
+       const VkImageAspectFlags                                formatAspect                    = getAspectFlags(mapVkFormat(imageParms.format));
        const VkImageMemoryBarrier                              imageBarrier                    =
        {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
                DE_NULL,                                                                        // const void*                          pNext;
                VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
                VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
-               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+               imageParms.operationLayout,                                     // VkImageLayout                        oldLayout;
                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                image,                                                                          // VkImage                                      image;
                {                                                                                       // VkImageSubresourceRange      subresourceRange;
-                       aspect,                                         // VkImageAspectFlags   aspectMask;
-                       0u,                                                     // deUint32                             baseMipLevel;
-                       1u,                                                     // deUint32                             mipLevels;
-                       0u,                                                     // deUint32                             baseArraySlice;
-                       1u                                                      // deUint32                             arraySize;
+                       formatAspect,                   // VkImageAspectFlags   aspectMask;
+                       0u,                                             // deUint32                             baseMipLevel;
+                       1u,                                             // deUint32                             mipLevels;
+                       0u,                                             // deUint32                             baseArraySlice;
+                       getArraySize(imageParms)// deUint32                             arraySize;
                }
        };
 
@@ -592,21 +698,21 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                  image,
                VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
                VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        oldLayout;
-               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+               imageParms.operationLayout,                                     // VkImageLayout                        newLayout;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                image,                                                                          // VkImage                                      image;
                {
-                       aspect,                                                                 // VkImageAspectFlags   aspectMask;
+                       formatAspect,                                                           // VkImageAspectFlags   aspectMask;
                        0u,                                                                                     // deUint32                             baseMipLevel;
                        1u,                                                                                     // deUint32                             mipLevels;
                        0u,                                                                                     // deUint32                             baseArraySlice;
-                       1u,                                                                                     // deUint32                             arraySize;
+                       getArraySize(imageParms)                                        // deUint32                             arraySize;
                }                                                                                       // VkImageSubresourceRange      subresourceRange;
        };
 
        // Copy image to buffer
-       const VkExtent3D                        imageExtent             = { (deUint32)dst.getWidth(), (deUint32)dst.getHeight(), 1u };
+       const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
        const VkBufferImageCopy         copyRegion              =
        {
                0u,                                                                     // VkDeviceSize                         bufferOffset;
@@ -616,7 +722,7 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                    image,
                        aspect,                                                         // VkImageAspectFlags           aspect;
                        0u,                                                                     // deUint32                                     mipLevel;
                        0u,                                                                     // deUint32                                     baseArrayLayer;
-                       1u,                                                                     // deUint32                                     layerCount;
+                       getArraySize(imageParms),                       // deUint32                                     layerCount;
                },                                                                      // VkImageSubresourceLayers     imageSubresource;
                { 0, 0, 0 },                                            // VkOffset3D                           imageOffset;
                imageExtent                                                     // VkExtent3D                           imageExtent;
@@ -630,12 +736,21 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                  image,
                (const VkCommandBufferInheritanceInfo*)DE_NULL,
        };
 
-       VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
-       vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
-       vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
-       vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
-       VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
+       VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
+       vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
+       VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+
+       submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
+
+       // Read buffer data
+       invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
+       tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
+}
 
+void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
+{
        const VkSubmitInfo                                              submitInfo                              =
        {
                VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
@@ -644,45 +759,40 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                  image,
                DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
                (const VkPipelineStageFlags*)DE_NULL,
                1u,                                                             // deUint32                                     commandBufferCount;
-               &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
+               &cmdBuffer,                                             // const VkCommandBuffer*       pCommandBuffers;
                0u,                                                             // deUint32                                     signalSemaphoreCount;
                DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
        };
 
        VK_CHECK(vk.resetFences(device, 1, &m_fence.get()));
        VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), 0, ~(0ull) /* infinity */));
-
-       // Read buffer data
-       invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
-       tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
+       VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
 }
 
 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage        (vk::VkImage            image,
-                                                                                                                                                vk::VkFormat           format,
-                                                                                                                                                const VkExtent3D       imageSize)
+                                                                                                                                                const ImageParms&      parms)
 {
-       const tcu::TextureFormat                imageFormat     = mapVkFormat(format);
-       de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, imageSize.width, imageSize.height, imageSize.depth));
+       const tcu::TextureFormat                imageFormat     = mapVkFormat(parms.format);
+       de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width, parms.extent.height, parms.extent.depth));
 
        if (tcu::isCombinedDepthStencilType(imageFormat.type))
        {
                if (tcu::hasDepthComponent(imageFormat.order))
                {
-                       tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), imageSize.width, imageSize.height, imageSize.depth);
-                       readImageAspect(image, depthTexture.getAccess());
+                       tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
+                       readImageAspect(image, depthTexture.getAccess(), parms);
                        tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
                }
 
                if (tcu::hasStencilComponent(imageFormat.order))
                {
-                       tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), imageSize.width, imageSize.height, imageSize.depth);
-                       readImageAspect(image, stencilTexture.getAccess());
+                       tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
+                       readImageAspect(image, stencilTexture.getAccess(), parms);
                        tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
                }
        }
        else
-               readImageAspect(image, resultLevel->getAccess());
+               readImageAspect(image, resultLevel->getAccess(), parms);
 
        return resultLevel;
 }
@@ -695,6 +805,10 @@ public:
                                                                                CopyImageToImage                        (Context&       context,
                                                                                                                                         TestParams params);
        virtual tcu::TestStatus                         iterate                                         (void);
+
+protected:
+       virtual tcu::TestStatus                         checkTestResult                         (tcu::ConstPixelBufferAccess result);
+
 private:
        Move<VkImage>                                           m_source;
        de::MovePtr<Allocation>                         m_sourceImageAlloc;
@@ -707,22 +821,31 @@ private:
 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
        : CopiesAndBlittingTestInstance(context, params)
 {
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
        const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = context.getDefaultAllocator();
 
+       if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
+               (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
+       {
+               if (std::find(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1") == context.getDeviceExtensions().end())
+                       TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
+       }
+
        VkImageFormatProperties properties;
        if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
                                                                                                                                                                m_params.src.image.format,
-                                                                                                                                                               VK_IMAGE_TYPE_2D,
+                                                                                                                                                               m_params.src.image.imageType,
                                                                                                                                                                VK_IMAGE_TILING_OPTIMAL,
                                                                                                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
                                                                                                                                                                0,
                                                                                                                                                                &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
                (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
                                                                                                                                                                m_params.dst.image.format,
-                                                                                                                                                               VK_IMAGE_TYPE_2D,
+                                                                                                                                                               m_params.dst.image.imageType,
                                                                                                                                                                VK_IMAGE_TILING_OPTIMAL,
                                                                                                                                                                VK_IMAGE_USAGE_TRANSFER_DST_BIT,
                                                                                                                                                                0,
@@ -738,11 +861,11 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.src.image.imageType,                   // VkImageType                  imageType;
                        m_params.src.image.format,                              // VkFormat                             format;
-                       m_params.src.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.src.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -754,7 +877,7 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
                };
 
                m_source                                = createImage(vk, vkDevice, &sourceImageParams);
-               m_sourceImageAlloc              = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
+               m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
        }
 
@@ -765,11 +888,11 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.dst.image.imageType,                   // VkImageType                  imageType;
                        m_params.dst.image.format,                              // VkFormat                             format;
-                       m_params.dst.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.dst.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -781,7 +904,7 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
                };
 
                m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
-               m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
+               m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
        }
 }
@@ -791,19 +914,19 @@ tcu::TestStatus CopyImageToImage::iterate (void)
        const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
        const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
        m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
-                                                                                                                                                               m_params.src.image.extent.width,
-                                                                                                                                                               m_params.src.image.extent.height,
-                                                                                                                                                               m_params.src.image.extent.depth));
-       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_WHITE);
+                                                                                                                                                               (int)m_params.src.image.extent.width,
+                                                                                                                                                               (int)m_params.src.image.extent.height,
+                                                                                                                                                               (int)m_params.src.image.extent.depth));
+       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED);
        m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
-                                                                                                                                                                        (int)m_params.dst.image.extent.width,
-                                                                                                                                                                        (int)m_params.dst.image.extent.height,
-                                                                                                                                                                        (int)m_params.dst.image.extent.depth));
+                                                                                                                                                               (int)m_params.dst.image.extent.width,
+                                                                                                                                                               (int)m_params.dst.image.extent.height,
+                                                                                                                                                               (int)m_params.dst.image.extent.depth));
        generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_GRADIENT);
        generateExpectedResult();
 
-       uploadImage(m_sourceTextureLevel->getAccess(), m_source.get());
-       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
+       uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
+       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
 
        const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
        const VkDevice                          vkDevice                        = m_context.getDevice();
@@ -822,7 +945,7 @@ tcu::TestStatus CopyImageToImage::iterate (void)
                        VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
-                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
+                       m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                        m_source.get(),                                                         // VkImage                                      image;
@@ -831,7 +954,7 @@ tcu::TestStatus CopyImageToImage::iterate (void)
                                0u,                                                             // deUint32                             baseMipLevel;
                                1u,                                                             // deUint32                             mipLevels;
                                0u,                                                             // deUint32                             baseArraySlice;
-                               1u                                                              // deUint32                             arraySize;
+                               getArraySize(m_params.src.image)// deUint32                             arraySize;
                        }
                },
                // destination image
@@ -841,7 +964,7 @@ tcu::TestStatus CopyImageToImage::iterate (void)
                        VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
-                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+                       m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                        m_destination.get(),                                            // VkImage                                      image;
@@ -850,7 +973,7 @@ tcu::TestStatus CopyImageToImage::iterate (void)
                                0u,                                                             // deUint32                             baseMipLevel;
                                1u,                                                             // deUint32                             mipLevels;
                                0u,                                                             // deUint32                             baseArraySlice;
-                               1u                                                              // deUint32                             arraySize;
+                               getArraySize(m_params.dst.image)// deUint32                             arraySize;
                        }
                },
        };
@@ -865,46 +988,125 @@ tcu::TestStatus CopyImageToImage::iterate (void)
 
        VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
        vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
-       vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageCopies.data());
+       vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), imageCopies.data());
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
 
-       const VkSubmitInfo                              submitInfo                      =
+       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
+
+       de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
+
+       return checkTestResult(resultTextureLevel->getAccess());
+}
+
+tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
+{
+       const tcu::Vec4 fThreshold (0.0f);
+       const tcu::UVec4 uThreshold (0u);
+
+       if (tcu::isCombinedDepthStencilType(result.getFormat().type))
        {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
+               if (tcu::hasDepthComponent(result.getFormat().order))
+               {
+                       const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
+                       const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
+                       const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
 
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
+                       if (isFloatFormat(result.getFormat()))
+                       {
+                               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
+                                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       }
+                       else
+                       {
+                               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
+                                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       }
+               }
 
-       de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent);
+               if (tcu::hasStencilComponent(result.getFormat().order))
+               {
+                       const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
+                       const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
+                       const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
 
-       return checkTestResult(resultTextureLevel->getAccess());
+                       if (isFloatFormat(result.getFormat()))
+                       {
+                               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
+                                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       }
+                       else
+                       {
+                               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
+                                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       }
+               }
+       }
+       else
+       {
+               if (isFloatFormat(result.getFormat()))
+               {
+                       if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
+               else if (isSnormFormat(mapTextureFormat(result.getFormat())))
+               {
+                       // There may be an ambiguity between two possible binary representations of 1.0.
+                       // Get rid of that by expanding the data to floats and re-normalizing again.
+
+                       tcu::TextureLevel resultSnorm   (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
+                       {
+                               tcu::TextureLevel resultFloat   (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
+
+                               tcu::copy(resultFloat.getAccess(), result);
+                               tcu::copy(resultSnorm, resultFloat.getAccess());
+                       }
+
+                       tcu::TextureLevel expectedSnorm (m_expectedTextureLevel->getFormat(), m_expectedTextureLevel->getWidth(), m_expectedTextureLevel->getHeight(), m_expectedTextureLevel->getDepth());
+
+                       {
+                               tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
+
+                               tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel->getAccess());
+                               tcu::copy(expectedSnorm, expectedFloat.getAccess());
+                       }
+
+                       if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
+               else
+               {
+                       if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
+       }
+
+       return tcu::TestStatus::pass("CopiesAndBlitting test");
 }
 
 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
 {
-       VkOffset3D srcOffset    = region.imageCopy.srcOffset;
-       VkOffset3D dstOffset    = region.imageCopy.dstOffset;
-       VkExtent3D extent               = region.imageCopy.extent;
+       VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
+       VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
+       VkExtent3D      extent          = region.imageCopy.extent;
+
+       if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
+               dstOffset.z = srcOffset.z;
+       if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
+       {
+               srcOffset.z = dstOffset.z;
+               extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
+       }
+
 
        if (tcu::isCombinedDepthStencilType(src.getFormat().type))
        {
                DE_ASSERT(src.getFormat() == dst.getFormat());
+
                // Copy depth.
+               if (tcu::hasDepthComponent(src.getFormat().order))
                {
                        const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
-                       const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
-                       const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
-
+                       const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
                        tcu::copy(dstSubRegion, srcSubRegion);
                }
 
@@ -912,9 +1114,7 @@ void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src
                if (tcu::hasStencilComponent(src.getFormat().order))
                {
                        const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
-                       const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
-                       const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
-
+                       const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
                        tcu::copy(dstSubRegion, srcSubRegion);
                }
        }
@@ -966,7 +1166,9 @@ private:
 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
        : CopiesAndBlittingTestInstance (context, params)
 {
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
        const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = context.getDefaultAllocator();
@@ -986,7 +1188,7 @@ CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
                };
 
                m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
-               m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
+               m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
        }
 
@@ -1005,7 +1207,7 @@ CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
                };
 
                m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
-               m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
+               m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
        }
 }
@@ -1072,23 +1274,9 @@ tcu::TestStatus CopyBufferToBuffer::iterate (void)
        vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
        vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
 
-       const VkSubmitInfo                              submitInfo                      =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
 
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
 
        // Read buffer data
        de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
@@ -1149,7 +1337,9 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
        , m_textureFormat(mapVkFormat(testParams.src.image.format))
        , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
 {
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
        const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = context.getDefaultAllocator();
@@ -1161,11 +1351,11 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.src.image.imageType,                   // VkImageType                  imageType;
                        m_params.src.image.format,                              // VkFormat                             format;
-                       m_params.src.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.src.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -1177,7 +1367,7 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
                };
 
                m_source                        = createImage(vk, vkDevice, &sourceImageParams);
-               m_sourceImageAlloc      = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
+               m_sourceImageAlloc      = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
        }
 
@@ -1196,7 +1386,7 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
                };
 
                m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
-               m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
+               m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
        }
 }
@@ -1207,13 +1397,13 @@ tcu::TestStatus CopyImageToBuffer::iterate (void)
                                                                                                                                                                m_params.src.image.extent.width,
                                                                                                                                                                m_params.src.image.extent.height,
                                                                                                                                                                m_params.src.image.extent.depth));
-       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED);
+       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
        m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
        generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
 
        generateExpectedResult();
 
-       uploadImage(m_sourceTextureLevel->getAccess(), *m_source);
+       uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
        uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
 
        const DeviceInterface&          vk                      = m_context.getDeviceInterface();
@@ -1273,22 +1463,7 @@ tcu::TestStatus CopyImageToBuffer::iterate (void)
        vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
 
-       const VkSubmitInfo                              submitInfo                      =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
-
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
+       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
 
        // Read buffer data
        de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
@@ -1370,7 +1545,9 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
        , m_textureFormat(mapVkFormat(testParams.dst.image.format))
        , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
 {
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
        const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = context.getDefaultAllocator();
@@ -1390,7 +1567,7 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
                };
 
                m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
-               m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
+               m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
        }
 
@@ -1401,11 +1578,11 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.dst.image.imageType,                   // VkImageType                  imageType;
                        m_params.dst.image.format,                              // VkFormat                             format;
-                       m_params.dst.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.dst.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -1417,7 +1594,7 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
                };
 
                m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
-               m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
+               m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
        }
 }
@@ -1431,12 +1608,12 @@ tcu::TestStatus CopyBufferToImage::iterate (void)
                                                                                                                                                                        m_params.dst.image.extent.height,
                                                                                                                                                                        m_params.dst.image.extent.depth));
 
-       generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
+       generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
 
        generateExpectedResult();
 
        uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
-       uploadImage(m_destinationTextureLevel->getAccess(), *m_destination);
+       uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
 
        const DeviceInterface&          vk                      = m_context.getDeviceInterface();
        const VkDevice                          vkDevice        = m_context.getDevice();
@@ -1480,24 +1657,9 @@ tcu::TestStatus CopyBufferToImage::iterate (void)
        vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
 
-       const VkSubmitInfo                              submitInfo                      =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
-
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
+       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
 
-       de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent);
+       de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
 
        return checkTestResult(resultLevel->getAccess());
 }
@@ -1564,10 +1726,13 @@ protected:
        virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
        virtual void                                            generateExpectedResult                  (void);
 private:
-       bool                                                            checkClampedAndUnclampedResult  (const tcu::ConstPixelBufferAccess&     result,
+       bool                                                            checkLinearFilteredResult               (const tcu::ConstPixelBufferAccess&     result,
                                                                                                                                                 const tcu::ConstPixelBufferAccess&     clampedReference,
                                                                                                                                                 const tcu::ConstPixelBufferAccess&     unclampedReference,
-                                                                                                                                                VkImageAspectFlagBits                          aspect);
+                                                                                                                                                const tcu::TextureFormat&                      sourceFormat);
+       bool                                                            checkNearestFilteredResult              (const tcu::ConstPixelBufferAccess&     result,
+                                                                                                                                                const tcu::ConstPixelBufferAccess& source);
+
        Move<VkImage>                                           m_source;
        de::MovePtr<Allocation>                         m_sourceImageAlloc;
        Move<VkImage>                                           m_destination;
@@ -1579,7 +1744,9 @@ private:
 BlittingImages::BlittingImages (Context& context, TestParams params)
        : CopiesAndBlittingTestInstance(context, params)
 {
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
        const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
        const VkDevice                          vkDevice                        = context.getDevice();
        const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                        = context.getDefaultAllocator();
@@ -1632,11 +1799,11 @@ BlittingImages::BlittingImages (Context& context, TestParams params)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.src.image.imageType,                   // VkImageType                  imageType;
                        m_params.src.image.format,                              // VkFormat                             format;
-                       m_params.src.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.src.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -1648,7 +1815,7 @@ BlittingImages::BlittingImages (Context& context, TestParams params)
                };
 
                m_source = createImage(vk, vkDevice, &sourceImageParams);
-               m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
+               m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
        }
 
@@ -1659,11 +1826,11 @@ BlittingImages::BlittingImages (Context& context, TestParams params)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.dst.image.imageType,                   // VkImageType                  imageType;
                        m_params.dst.image.format,                              // VkFormat                             format;
-                       m_params.dst.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.dst.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -1675,7 +1842,7 @@ BlittingImages::BlittingImages (Context& context, TestParams params)
                };
 
                m_destination = createImage(vk, vkDevice, &destinationImageParams);
-               m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
+               m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
        }
 }
@@ -1696,8 +1863,8 @@ tcu::TestStatus BlittingImages::iterate (void)
        generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
        generateExpectedResult();
 
-       uploadImage(m_sourceTextureLevel->getAccess(), m_source.get());
-       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
+       uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
+       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
 
        const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
        const VkDevice                          vkDevice                        = m_context.getDevice();
@@ -1715,7 +1882,7 @@ tcu::TestStatus BlittingImages::iterate (void)
                VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
                VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
-               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
+               m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                m_source.get(),                                                         // VkImage                                      image;
@@ -1735,7 +1902,7 @@ tcu::TestStatus BlittingImages::iterate (void)
                VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
                VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
-               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+               m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                m_destination.get(),                                            // VkImage                                      image;
@@ -1758,28 +1925,12 @@ tcu::TestStatus BlittingImages::iterate (void)
 
        VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
        vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
-       vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
-       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
+       vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
 
-       const VkSubmitInfo                              submitInfo                      =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
-
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
-
-       de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent);
+       de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
 
        return checkTestResult(resultTextureLevel->getAccess());
 }
@@ -1836,52 +1987,28 @@ tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
                return threshold;
 }
 
-tcu::TextureFormat getFormatAspect (VkFormat format, VkImageAspectFlagBits aspect)
-{
-       const tcu::TextureFormat        baseFormat      = mapVkFormat(format);
-
-       if (isCombinedDepthStencilType(baseFormat.type))
-       {
-               if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
-                       return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_DEPTH);
-               else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
-                       return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_STENCIL);
-               else
-                       DE_FATAL("Invalid aspect");
-       }
-
-       return baseFormat;
-}
-
-bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBufferAccess&        result,
-                                                                                                        const tcu::ConstPixelBufferAccess& clampedExpected,
-                                                                                                        const tcu::ConstPixelBufferAccess& unclampedExpected,
-                                                                                                        VkImageAspectFlagBits                          aspect)
+bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess&     result,
+                                                                                               const tcu::ConstPixelBufferAccess&      clampedExpected,
+                                                                                               const tcu::ConstPixelBufferAccess&      unclampedExpected,
+                                                                                               const tcu::TextureFormat&                       srcFormat)
 {
        tcu::TestLog&                           log                     (m_context.getTestContext().getLog());
-       const bool                                      isLinear        = m_params.filter == VK_FILTER_LINEAR;
-       const tcu::TextureFormat        srcFormat       = getFormatAspect(m_params.src.image.format, aspect);
        const tcu::TextureFormat        dstFormat       = result.getFormat();
        bool                                            isOk            = false;
 
-       DE_ASSERT(dstFormat == getFormatAspect(m_params.dst.image.format, aspect));
-
-       if (isLinear)
-               log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
+       log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
 
        if (isFloatFormat(dstFormat))
        {
                const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
-               const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2 : 1);
+               const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
                const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
                const tcu::Vec4 threshold       = tcu::max(srcMaxDiff, dstMaxDiff);
 
                isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
+               log << tcu::TestLog::EndSection;
 
-               if (isLinear)
-                       log << tcu::TestLog::EndSection;
-
-               if (!isOk && isLinear)
+               if (!isOk)
                {
                        log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
                        isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
@@ -1897,61 +2024,318 @@ bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBuffer
                        threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
 
                isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
+               log << tcu::TestLog::EndSection;
 
-               if (isLinear)
-                       log << tcu::TestLog::EndSection;
-
-               if (!isOk && isLinear)
+               if (!isOk)
                {
                        log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
                        isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
                        log << tcu::TestLog::EndSection;
                }
        }
+
        return isOk;
 }
 
-tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
+//! Utility to encapsulate coordinate computation and loops.
+struct CompareEachPixelInEachRegion
 {
-       DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
+       virtual          ~CompareEachPixelInEachRegion  (void) {}
+       virtual bool compare                                            (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const = 0;
 
-       if (tcu::isCombinedDepthStencilType(result.getFormat().type))
+       bool forEach (const void*                                               pUserData,
+                                 const std::vector<CopyRegion>&        regions,
+                                 const int                                                     sourceWidth,
+                                 const int                                                     sourceHeight,
+                                 const tcu::PixelBufferAccess&         errorMask) const
        {
-               if (tcu::hasDepthComponent(result.getFormat().order))
+               bool compareOk = true;
+
+               for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
                {
-                       const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
-                       const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
-                       const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
-                       const tcu::ConstPixelBufferAccess               unclampedExpected       = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
+                       const VkImageBlit& blit = regionIter->imageBlit;
+
+                       const int       dx              = deSign32(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
+                       const int       dy              = deSign32(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
+                       const float     xScale  = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
+                       const float     yScale  = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
+                       const float srcInvW     = 1.0f / static_cast<float>(sourceWidth);
+                       const float srcInvH     = 1.0f / static_cast<float>(sourceHeight);
 
-                       if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT))
+                       for (int y = blit.dstOffsets[0].y; y < blit.dstOffsets[1].y; y += dy)
+                       for (int x = blit.dstOffsets[0].x; x < blit.dstOffsets[1].x; x += dx)
                        {
-                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+                               const tcu::Vec2 srcNormCoord
+                               (
+                                       (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
+                                       (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH
+                               );
+
+                               if (!compare(pUserData, x, y, srcNormCoord))
+                               {
+                                       errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
+                                       compareOk = false;
+                               }
                        }
                }
+               return compareOk;
+       }
+};
 
-               if (tcu::hasStencilComponent(result.getFormat().order))
+tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
+{
+       const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
+       const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
+
+       if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
+       {
+               return getFormatThreshold(format);
+       }
+       else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+                        channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
+       {
+               const bool      isSigned        = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
+               const float     range           = isSigned ? 1.0f - (-1.0f)
+                                                                                  : 1.0f -   0.0f;
+
+               tcu::Vec4 v;
+               for (int i = 0; i < 4; ++i)
                {
-                       const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
-                       const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
-                       const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
-                       const tcu::ConstPixelBufferAccess               unclampedExpected       = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
+                       if (bitDepth[i] == 0)
+                               v[i] = 1.0f;
+                       else
+                               v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
+               }
+               return v;
+       }
+       else
+       {
+               DE_ASSERT(0);
+               return tcu::Vec4();
+       }
+}
+
+bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&       source,
+                                                         const tcu::ConstPixelBufferAccess&    result,
+                                                         const tcu::PixelBufferAccess&                 errorMask,
+                                                         const std::vector<CopyRegion>&                regions)
+{
+       const tcu::Sampler              sampler         (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
+       tcu::LookupPrecision    precision;
+
+       {
+               const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
+               const tcu::Vec4         srcMaxDiff      = getFloatOrFixedPointFormatThreshold(source.getFormat());
+               const tcu::Vec4         dstMaxDiff      = getFloatOrFixedPointFormatThreshold(result.getFormat());
+
+               precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
+               precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
+       }
+
+       const struct Capture
+       {
+               const tcu::ConstPixelBufferAccess&      source;
+               const tcu::ConstPixelBufferAccess&      result;
+               const tcu::Sampler&                                     sampler;
+               const tcu::LookupPrecision&                     precision;
+               const bool                                                      isSRGB;
+       } capture =
+       {
+               source, result, sampler, precision, tcu::isSRGB(result.getFormat())
+       };
+
+       const struct Loop : CompareEachPixelInEachRegion
+       {
+               Loop (void) {}
+
+               bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
+               {
+                       const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
+                       const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
+                       tcu::Vec4                                               dstColor                        = c.result.getPixel(x, y);
+
+                       // TexLookupVerifier performs a conversion to linear space, so we have to as well
+                       if (c.isSRGB)
+                               dstColor = tcu::sRGBToLinear(dstColor);
+
+                       return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
+               }
+       } loop;
+
+       return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
+}
+
+bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
+                                                       const tcu::ConstPixelBufferAccess&      result,
+                                                       const tcu::PixelBufferAccess&           errorMask,
+                                                       const std::vector<CopyRegion>&          regions)
+{
+       const tcu::Sampler              sampler         (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
+       tcu::IntLookupPrecision precision;
+
+       {
+               const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
+               const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
+
+               for (deUint32 i = 0; i < 4; ++i) {
+                       precision.colorThreshold[i]     = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
+                       precision.colorMask[i]          = dstBitDepth[i] != 0;
+               }
+       }
+
+       // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
+       // does the conversion on the fly without wasting memory, but this approach is more straightforward.
+       tcu::TextureLevel                               convertedSourceTexture  (result.getFormat(), source.getWidth(), source.getHeight());
+       const tcu::PixelBufferAccess    convertedSource                 = convertedSourceTexture.getAccess();
+
+       for (int y = 0; y < source.getHeight(); ++y)
+       for (int x = 0; x < source.getWidth();  ++x)
+               convertedSource.setPixel(source.getPixelInt(x, y), x, y);       // will be clamped to max. representable value
+
+       const struct Capture
+       {
+               const tcu::ConstPixelBufferAccess&      source;
+               const tcu::ConstPixelBufferAccess&      result;
+               const tcu::Sampler&                                     sampler;
+               const tcu::IntLookupPrecision&          precision;
+       } capture =
+       {
+               convertedSource, result, sampler, precision
+       };
+
+       const struct Loop : CompareEachPixelInEachRegion
+       {
+               Loop (void) {}
+
+               bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
+               {
+                       const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
+                       const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
+                       const tcu::IVec4                                dstColor                        = c.result.getPixelInt(x, y);
+
+                       return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
+               }
+       } loop;
+
+       return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
+}
+
+bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&    result,
+                                                                                                const tcu::ConstPixelBufferAccess& source)
+{
+       tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
+       const tcu::TextureFormat                dstFormat               = result.getFormat();
+       const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
+
+       tcu::TextureLevel               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
+       tcu::PixelBufferAccess  errorMask                       = errorMaskStorage.getAccess();
+       tcu::Vec4                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
+       tcu::Vec4                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
+       bool                                    ok                                      = false;
+
+       tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
+
+       if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
+               dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
+       {
+               ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
+       }
+       else
+               ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);
+
+       if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
+               tcu::computePixelScaleBias(result, pixelScale, pixelBias);
+
+       if (!ok)
+       {
+               log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
+                       << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+                       << tcu::TestLog::Image("ErrorMask",     "Error mask", errorMask)
+                       << tcu::TestLog::EndImageSet;
+       }
+       else
+       {
+               log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
+                       << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+                       << tcu::TestLog::EndImageSet;
+       }
+
+       return ok;
+}
+
+tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
+{
+       DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
+       const std::string failMessage("Result image is incorrect");
+
+       if (m_params.filter == VK_FILTER_LINEAR)
+       {
+               if (tcu::isCombinedDepthStencilType(result.getFormat().type))
+               {
+                       if (tcu::hasDepthComponent(result.getFormat().order))
+                       {
+                               const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
+                               const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
+                               const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
+                               const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
+                               const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
+
+                               if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
+                                       return tcu::TestStatus::fail(failMessage);
+                       }
 
-                       if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT))
+                       if (tcu::hasStencilComponent(result.getFormat().order))
                        {
-                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+                               const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
+                               const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
+                               const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
+                               const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
+                               const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
+
+                               if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
+                                       return tcu::TestStatus::fail(failMessage);
                        }
                }
+               else
+               {
+                       const tcu::TextureFormat        sourceFormat    = mapVkFormat(m_params.src.image.format);
+
+                       if (!checkLinearFilteredResult(result, m_expectedTextureLevel->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
+                               return tcu::TestStatus::fail(failMessage);
+               }
        }
-       else
+       else // NEAREST filtering
        {
-               if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT))
+               if (tcu::isCombinedDepthStencilType(result.getFormat().type))
                {
-                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       if (tcu::hasDepthComponent(result.getFormat().order))
+                       {
+                               const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_DEPTH;
+                               const tcu::ConstPixelBufferAccess               depthResult             = tcu::getEffectiveDepthStencilAccess(result, mode);
+                               const tcu::ConstPixelBufferAccess               depthSource             = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
+
+                               if (!checkNearestFilteredResult(depthResult, depthSource))
+                                       return tcu::TestStatus::fail(failMessage);
+                       }
+
+                       if (tcu::hasStencilComponent(result.getFormat().order))
+                       {
+                               const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_STENCIL;
+                               const tcu::ConstPixelBufferAccess               stencilResult   = tcu::getEffectiveDepthStencilAccess(result, mode);
+                               const tcu::ConstPixelBufferAccess               stencilSource   = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
+
+                               if (!checkNearestFilteredResult(stencilResult, stencilSource))
+                                       return tcu::TestStatus::fail(failMessage);
+                       }
+               }
+               else
+               {
+                       if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
+                               return tcu::TestStatus::fail(failMessage);
                }
        }
 
-       return tcu::TestStatus::pass("CopiesAndBlitting test");
+       return tcu::TestStatus::pass("Pass");
 }
 
 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
@@ -1975,8 +2359,128 @@ void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::Cons
                dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, (float)regionOffset.x + ((float)x+0.5f)*sX, (float)regionOffset.y + ((float)y+0.5f)*sY, 0)), x, y);
 }
 
+void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
+{
+       DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
+
+       tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
+                                                filter, filter, 0.0f, false);
+
+       const float sX = (float)src.getWidth() / (float)dst.getWidth();
+       const float sY = (float)src.getHeight() / (float)dst.getHeight();
+       const float sZ = (float)src.getDepth() / (float)dst.getDepth();
+
+       tcu::Mat2 rotMatrix;
+       rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
+       rotMatrix(0,1) = 0.0f;
+       rotMatrix(1,0) = 0.0f;
+       rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
+
+       const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
+       const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
+
+       if (dst.getDepth() == 1 && src.getDepth() == 1)
+       {
+               for (int y = 0; y < dst.getHeight(); ++y)
+               for (int x = 0; x < dst.getWidth(); ++x)
+               {
+                       const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
+                       dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset);
+               }
+       }
+       else
+       {
+               for (int z = 0; z < dst.getDepth(); ++z)
+               for (int y = 0; y < dst.getHeight(); ++y)
+               for (int x = 0; x < dst.getWidth(); ++x)
+               {
+                       const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
+                       dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z);
+               }
+       }
+}
+
+void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
+{
+       const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
+       const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
+       const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
+       const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
+
+       if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
+       {
+               //sourceRegion
+               region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
+               region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
+
+               region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
+               region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
+
+               //destinationRegion
+               region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
+               region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
+
+               region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
+               region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
+       }
+}
+
+MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
+{
+       if (x1.x >= x2.x && x1.y >= x2.y)
+       {
+               return MIRROR_MODE_XY;
+       }
+       else if (x1.x <= x2.x && x1.y <= x2.y)
+       {
+               return MIRROR_MODE_NONE;
+       }
+       else if (x1.x <= x2.x && x1.y >= x2.y)
+       {
+               return MIRROR_MODE_Y;
+       }
+       else if (x1.x >= x2.x && x1.y <= x2.y)
+       {
+               return MIRROR_MODE_X;
+       }
+       return MIRROR_MODE_LAST;
+}
+
+MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
+{
+       const MirrorMode source          = getMirrorMode(s1, s2);
+       const MirrorMode destination = getMirrorMode(d1, d2);
+
+       if (source == destination)
+       {
+               return MIRROR_MODE_NONE;
+       }
+       else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
+                        (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
+       {
+               return MIRROR_MODE_Y;
+       }
+       else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
+                        (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
+       {
+               return MIRROR_MODE_X;
+       }
+       else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
+       {
+               return MIRROR_MODE_XY;
+       }
+       return MIRROR_MODE_LAST;
+}
+
 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
 {
+       const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
+                                                                                               region.imageBlit.srcOffsets[1],
+                                                                                               region.imageBlit.dstOffsets[0],
+                                                                                               region.imageBlit.dstOffsets[1]);
+
+       flipCoordinates(region, mirrorMode);
+
        const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
        const VkOffset3D                                        srcExtent               =
        {
@@ -2016,7 +2520,7 @@ void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
                {
                        const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
                        const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
-                       tcu::scale(dstSubRegion, srcSubRegion, filter);
+                       blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
 
                        if (filter == tcu::Sampler::LINEAR)
                        {
@@ -2030,7 +2534,7 @@ void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
        {
                const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
                const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
-               tcu::scale(dstSubRegion, srcSubRegion, filter);
+               blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
 
                if (filter == tcu::Sampler::LINEAR)
                {
@@ -2055,7 +2559,10 @@ void BlittingImages::generateExpectedResult (void)
        }
 
        for (deUint32 i = 0; i < m_params.regions.size(); i++)
-               copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
+       {
+               CopyRegion region = m_params.regions[i];
+               copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), region);
+       }
 }
 
 class BlittingTestCase : public vkt::TestCase
@@ -2079,14 +2586,17 @@ private:
 
 // Resolve image to image.
 
+enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
 class ResolveImageToImage : public CopiesAndBlittingTestInstance
 {
 public:
-                                                                                               ResolveImageToImage                     (Context&       context,
-                                                                                                                                                        TestParams params);
+                                                                                               ResolveImageToImage                     (Context&                                                       context,
+                                                                                                                                                        TestParams                                                     params,
+                                                                                                                                                        const ResolveImageToImageOptions       options);
        virtual tcu::TestStatus                                         iterate                                         (void);
 protected:
        virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result);
+       void                                                                            copyMSImageToMSImage            (void);
 private:
        Move<VkImage>                                                           m_multisampledImage;
        de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
@@ -2094,54 +2604,55 @@ private:
        Move<VkImage>                                                           m_destination;
        de::MovePtr<Allocation>                                         m_destinationImageAlloc;
 
-       virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
+       Move<VkImage>                                                           m_multisampledCopyImage;
+       de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
+
+       const ResolveImageToImageOptions                        m_options;
+
+       virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
+                                                                                                                                                        tcu::PixelBufferAccess                 dst,
+                                                                                                                                                        CopyRegion                                             region);
 };
 
-ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
-       : CopiesAndBlittingTestInstance(context, params)
+ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
+       : CopiesAndBlittingTestInstance (context, params)
+       , m_options                                             (options)
 {
        const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
 
        if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
                throw tcu::NotSupportedError("Unsupported number of rasterization samples");
 
+       const InstanceInterface&        vki                                             = context.getInstanceInterface();
        const DeviceInterface&          vk                                              = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice                    = context.getPhysicalDevice();
        const VkDevice                          vkDevice                                = context.getDevice();
        const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
        Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
 
        const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
-
-       Move<VkImageView>                       sourceAttachmentView;
-
        Move<VkRenderPass>                      renderPass;
-       Move<VkFramebuffer>                     framebuffer;
 
-       Move<VkShaderModule>            vertexShaderModule;
-       Move<VkShaderModule>            fragmentShaderModule;
+       Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
+       Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
+       std::vector<tcu::Vec4>          vertices;
 
        Move<VkBuffer>                          vertexBuffer;
-       std::vector<tcu::Vec4>          vertices;
        de::MovePtr<Allocation>         vertexBufferAlloc;
 
        Move<VkPipelineLayout>          pipelineLayout;
        Move<VkPipeline>                        graphicsPipeline;
 
-       Move<VkCommandPool>                     cmdPool;
-       Move<VkCommandBuffer>           cmdBuffer;
-
-       Move<VkFence>                           fence;
-
        VkImageFormatProperties properties;
        if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
                                                                                                                                                                m_params.src.image.format,
-                                                                                                                                                               VK_IMAGE_TYPE_2D,
+                                                                                                                                                               m_params.src.image.imageType,
                                                                                                                                                                VK_IMAGE_TILING_OPTIMAL,
                                                                                                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
                                                                                                                                                                &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
                (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
                                                                                                                                                                m_params.dst.image.format,
-                                                                                                                                                               VK_IMAGE_TYPE_2D,
+                                                                                                                                                               m_params.dst.image.imageType,
                                                                                                                                                                VK_IMAGE_TILING_OPTIMAL,
                                                                                                                                                                VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
                                                                                                                                                                &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
@@ -2151,30 +2662,57 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
 
        // Create color image.
        {
-               const VkImageCreateInfo colorImageParams        =
-               {
-                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
-                       DE_NULL,                                                                                                                                        // const void*                          pNext;
-                       0u,                                                                                                                                                     // VkImageCreateFlags           flags;
-                       VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
-                       m_params.src.image.format,                                                                                                      // VkFormat                                     format;
-                       m_params.src.image.extent,                                                                                                      // VkExtent3D                           extent;
-                       1u,                                                                                                                                                     // deUint32                                     mipLevels;
-                       1u,                                                                                                                                                     // deUint32                                     arrayLayers;
-                       rasterizationSamples,                                                                                                           // VkSampleCountFlagBits        samples;
-                       VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
-                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
-                       VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
-                       1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
-                       &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
+               VkImageCreateInfo       colorImageParams        =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                                                                // const void*                          pNext;
+                       0u,                                                                                                                                             // VkImageCreateFlags           flags;
+                       m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
+                       m_params.src.image.format,                                                                                              // VkFormat                                     format;
+                       getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
+                       1u,                                                                                                                                             // deUint32                                     mipLevels;
+                       getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
+                       rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
+                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
                };
 
-               m_multisampledImage                     = createImage(vk, vkDevice, &colorImageParams);
+               m_multisampledImage                                             = createImage(vk, vkDevice, &colorImageParams);
 
                // Allocate and bind color image memory.
-               m_multisampledImageAlloc                = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage), MemoryRequirement::Any);
+               m_multisampledImageAlloc                                = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
+
+               switch (m_options)
+               {
+                       case COPY_MS_IMAGE_TO_MS_IMAGE:
+                       {
+                               colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+                               m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
+                               // Allocate and bind color image memory.
+                               m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
+                               VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
+                               break;
+                       }
+
+                       case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
+                       {
+                               colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+                               colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
+                               m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
+                               // Allocate and bind color image memory.
+                               m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
+                               VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
+                               break;
+                       }
+
+                       default :
+                               break;
+               }
        }
 
        // Create destination image.
@@ -2184,11 +2722,11 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                // const void*                  pNext;
                        0u,                                                                             // VkImageCreateFlags   flags;
-                       VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
+                       m_params.dst.image.imageType,                   // VkImageType                  imageType;
                        m_params.dst.image.format,                              // VkFormat                             format;
-                       m_params.dst.image.extent,                              // VkExtent3D                   extent;
+                       getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
                        1u,                                                                             // deUint32                             mipLevels;
-                       1u,                                                                             // deUint32                             arraySize;
+                       getArraySize(m_params.dst.image),               // deUint32                             arraySize;
                        VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
                        VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -2200,28 +2738,32 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                };
 
                m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
-               m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
+               m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
        }
 
-       // Create color attachment view.
+       // Barriers for copying image to buffer
+       VkImageMemoryBarrier            srcImageBarrier         =
        {
-               const VkImageViewCreateInfo     colorAttachmentViewParams       =
-               {
-                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
-                       DE_NULL,                                                                                // const void*                          pNext;
-                       0u,                                                                                             // VkImageViewCreateFlags       flags;
-                       *m_multisampledImage,                                                   // VkImage                                      image;
-                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
-                       m_params.src.image.format,                                              // VkFormat                                     format;
-                       componentMappingRGBA,                                                   // VkComponentMapping           components;
-                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
-               };
-
-               sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
-       }
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+               DE_NULL,                                                                        // const void*                          pNext;
+               0u,                                                                                     // VkAccessFlags                        srcAccessMask;
+               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
+               VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+               m_multisampledImage.get(),                                      // VkImage                                      image;
+               {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                       VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
+                       0u,                                                                     // deUint32                             baseMipLevel;
+                       1u,                                                                     // deUint32                             mipLevels;
+                       0u,                                                                     // deUint32                             baseArraySlice;
+                       getArraySize(m_params.src.image)        // deUint32                             arraySize;
+               }
+       };
 
-       // Create render pass.
+               // Create render pass.
        {
                const VkAttachmentDescription   attachmentDescriptions[1]       =
                {
@@ -2274,29 +2816,6 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
        }
 
-       // Create framebuffer
-       {
-               const VkImageView                               attachments[1]          =
-               {
-                       *sourceAttachmentView,
-               };
-
-               const VkFramebufferCreateInfo   framebufferParams       =
-               {
-                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
-                       DE_NULL,                                                                                        // const void*                                  pNext;
-                       0u,                                                                                                     // VkFramebufferCreateFlags             flags;
-                       *renderPass,                                                                            // VkRenderPass                                 renderPass;
-                       1u,                                                                                                     // deUint32                                             attachmentCount;
-                       attachments,                                                                            // const VkImageView*                   pAttachments;
-                       m_params.src.image.extent.width,                                        // deUint32                                             width;
-                       m_params.src.image.extent.height,                                       // deUint32                                             height;
-                       1u                                                                                                      // deUint32                                             layers;
-               };
-
-               framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
-       }
-
        // Create pipeline layout
        {
                const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
@@ -2313,197 +2832,19 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
        }
 
-       // Create shaders
+       // Create upper half triangle.
        {
-               vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
-               fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
-       }
-
-       // Create pipeline
-       {
-               const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]                            =
-               {
-                       {
-                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
-                               DE_NULL,                                                                                                        // const void*                                                  pNext;
-                               0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
-                               VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
-                               *vertexShaderModule,                                                                            // VkShaderModule                                               module;
-                               "main",                                                                                                         // const char*                                                  pName;
-                               DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
-                       },
-                       {
-                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
-                               DE_NULL,                                                                                                        // const void*                                                  pNext;
-                               0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
-                               VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
-                               *fragmentShaderModule,                                                                          // VkShaderModule                                               module;
-                               "main",                                                                                                         // const char*                                                  pName;
-                               DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
-                       }
-               };
-
-               const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
-               {
-                       0u,                                                                     // deUint32                             binding;
-                       sizeof(tcu::Vec4),                                      // deUint32                             stride;
-                       VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
-               };
-
-               const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[1]     =
-               {
-                       {
-                               0u,                                                                     // deUint32     location;
-                               0u,                                                                     // deUint32     binding;
-                               VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
-                               0u                                                                      // deUint32     offset;
-                       }
-               };
-
-               const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                          =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                                // const void*                                                          pNext;
-                       0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
-                       1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
-                       &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
-                       1u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
-                       vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
-               };
-
-               const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                        =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                                // const void*                                                          pNext;
-                       0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
-                       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
-                       false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
-               };
-
-               const VkViewport        viewport        =
-               {
-                       0.0f,                                                                           // float        x;
-                       0.0f,                                                                           // float        y;
-                       (float)m_params.src.image.extent.width,         // float        width;
-                       (float)m_params.src.image.extent.height,        // float        height;
-                       0.0f,                                                                           // float        minDepth;
-                       1.0f                                                                            // float        maxDepth;
-               };
-
-               const VkRect2D          scissor         =
-               {
-                       { 0, 0 },                                                                                                                               // VkOffset2D   offset;
-                       { m_params.src.image.extent.width, m_params.src.image.extent.height }   // VkExtent2D   extent;
-               };
-
-               const VkPipelineViewportStateCreateInfo                 viewportStateParams             =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
-                       DE_NULL,                                                                                                                // const void*                                                  pNext;
-                       0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
-                       1u,                                                                                                                             // deUint32                                                             viewportCount;
-                       &viewport,                                                                                                              // const VkViewport*                                    pViewports;
-                       1u,                                                                                                                             // deUint32                                                             scissorCount;
-                       &scissor                                                                                                                // const VkRect2D*                                              pScissors;
-               };
-
-               const VkPipelineRasterizationStateCreateInfo    rasterStateParams               =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                                // const void*                                                          pNext;
-                       0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
-                       false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
-                       false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
-                       VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
-                       VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
-                       VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
-                       VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
-                       1.0f                                                                                                                    // float                                                                        lineWidth;
-               };
-
-               const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                                // const void*                                                          pNext;
-                       0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
-                       rasterizationSamples,                                                                                   // VkSampleCountFlagBits                                        rasterizationSamples;
-                       VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
-                       0.0f,                                                                                                                   // float                                                                        minSampleShading;
-                       DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
-                       VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
-                       VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
-               };
-
-               const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState       =
-               {
-                       false,                                                                                                          // VkBool32                     blendEnable;
-                       VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendColor;
-                       VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendColor;
-                       VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpColor;
-                       VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendAlpha;
-                       VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendAlpha;
-                       VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpAlpha;
-                       (VK_COLOR_COMPONENT_R_BIT |
-                        VK_COLOR_COMPONENT_G_BIT |
-                        VK_COLOR_COMPONENT_B_BIT |
-                        VK_COLOR_COMPONENT_A_BIT)                                                                      // VkChannelFlags       channelWriteMask;
-               };
-
-               const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams   =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
-                       DE_NULL,                                                                                                        // const void*                                                                  pNext;
-                       0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
-                       false,                                                                                                          // VkBool32                                                                             logicOpEnable;
-                       VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
-                       1u,                                                                                                                     // deUint32                                                                             attachmentCount;
-                       &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
-                       { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
-               };
-
-               const VkGraphicsPipelineCreateInfo                      graphicsPipelineParams  =
-               {
-                       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
-                       DE_NULL,                                                                                        // const void*                                                                          pNext;
-                       0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
-                       2u,                                                                                                     // deUint32                                                                                     stageCount;
-                       shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
-                       &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
-                       &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
-                       DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
-                       &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
-                       &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
-                       &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
-                       DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
-                       &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
-                       DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
-                       *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
-                       *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
-                       0u,                                                                                                     // deUint32                                                                                     subpass;
-                       0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
-                       0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
-               };
-
-               graphicsPipeline        = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
+               const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
+               const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
+               const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
+               // Add triangle.
+               vertices.push_back(a);
+               vertices.push_back(c);
+               vertices.push_back(b);
        }
 
        // Create vertex buffer.
        {
-               // Create upper half triangle.
-               {
-                       const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
-                       const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
-                       const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
-
-                       // Add triangle.
-                       vertices.push_back(a);
-                       vertices.push_back(c);
-                       vertices.push_back(b);
-               }
-
                const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
                const VkBufferCreateInfo        vertexBufferParams      =
                {
@@ -2518,8 +2859,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                };
 
                vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
-               vertexBufferAlloc       = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
-
+               vertexBufferAlloc       = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
                VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
 
                // Load vertices into vertex buffer.
@@ -2527,128 +2867,268 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params)
                flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize);
        }
 
-       // Create command pool
        {
-               const VkCommandPoolCreateInfo cmdPoolParams =
-               {
-                       VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                              sType;
-                       DE_NULL,                                                                                // const void*                                  pNext;
-                       VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags             flags;
-                       queueFamilyIndex,                                                               // deUint32                                             queueFamilyIndex;
-               };
+               Move<VkFramebuffer>             framebuffer;
+               Move<VkImageView>               sourceAttachmentView;
 
-               cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
-       }
-
-       // Create command buffer
-       {
-               const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
+               // Create color attachment view.
                {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
-                       DE_NULL,                                                                                // const void*                          pNext;
-                       *cmdPool,                                                                               // VkCommandPool                        commandPool;
-                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level;
-                       1u                                                                                              // deUint32                             bufferCount;
-               };
+                       const VkImageViewCreateInfo     colorAttachmentViewParams       =
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
+                               DE_NULL,                                                                                                // const void*                          pNext;
+                               0u,                                                                                                             // VkImageViewCreateFlags       flags;
+                               *m_multisampledImage,                                                                   // VkImage                                      image;
+                               VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
+                               m_params.src.image.format,                                                              // VkFormat                                     format;
+                               componentMappingRGBA,                                                                   // VkComponentMapping           components;
+                               { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+                       };
+                       sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
+               }
 
-               const VkCommandBufferBeginInfo cmdBufferBeginInfo =
+               // Create framebuffer
                {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
-                       DE_NULL,                                                                                // const void*                                          pNext;
-                       0u,                                                                                             // VkCommandBufferUsageFlags            flags;
-                       (const VkCommandBufferInheritanceInfo*)DE_NULL,
-               };
+                       const VkImageView                               attachments[1]          =
+                       {
+                                       *sourceAttachmentView,
+                       };
 
-               const VkClearValue clearValue = makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f);
+                       const VkFramebufferCreateInfo   framebufferParams       =
+                       {
+                                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
+                                       DE_NULL,                                                                                        // const void*                                  pNext;
+                                       0u,                                                                                                     // VkFramebufferCreateFlags             flags;
+                                       *renderPass,                                                                            // VkRenderPass                                 renderPass;
+                                       1u,                                                                                                     // deUint32                                             attachmentCount;
+                                       attachments,                                                                            // const VkImageView*                   pAttachments;
+                                       m_params.src.image.extent.width,                                        // deUint32                                             width;
+                                       m_params.src.image.extent.height,                                       // deUint32                                             height;
+                                       1u                                                                                                      // deUint32                                             layers;
+                       };
 
-               const VkClearValue clearValues[1] =
-               {
-                       clearValue
-               };
+                       framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
+               }
 
-               const VkRenderPassBeginInfo renderPassBeginInfo =
+               // Create pipeline
                {
-                       VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
-                       DE_NULL,                                                                                                // const void*                  pNext;
-                       *renderPass,                                                                                    // VkRenderPass                 renderPass;
-                       *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
+                       const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]                            =
                        {
-                               { 0, 0 },
-                               { m_params.src.image.extent.width, m_params.src.image.extent.height }
-                       },                                                                                                              // VkRect2D                             renderArea;
-                       1u,                                                                                                             // deUint32                             clearValueCount;
-                       clearValues                                                                                             // const VkClearValue*  pClearValues;
-               };
+                               {
+                                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
+                                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                                       0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
+                                       VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
+                                       *vertexShaderModule,                                                                            // VkShaderModule                                               module;
+                                       "main",                                                                                                         // const char*                                                  pName;
+                                       DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
+                               },
+                               {
+                                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
+                                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                                       0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
+                                       VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
+                                       *fragmentShaderModule,                                                                          // VkShaderModule                                               module;
+                                       "main",                                                                                                         // const char*                                                  pName;
+                                       DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
+                               }
+                       };
 
-               // Barriers for copying image to buffer
-               const VkImageMemoryBarrier              srcImageBarrier         =
-               {
-                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
-                       DE_NULL,                                                                        // const void*                          pNext;
-                       0u,                                                                                     // VkAccessFlags                        srcAccessMask;
-                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
-                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
-                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
-                       m_multisampledImage.get(),                                      // VkImage                                      image;
-                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
-                               VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
-                               0u,                                                             // deUint32                             baseMipLevel;
-                               1u,                                                             // deUint32                             mipLevels;
-                               0u,                                                             // deUint32                             baseArraySlice;
-                               1u                                                              // deUint32                             arraySize;
-                       }
-               };
+                       const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
+                       {
+                                       0u,                                                                     // deUint32                             binding;
+                                       sizeof(tcu::Vec4),                                      // deUint32                             stride;
+                                       VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
+                       };
 
-               cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
+                       const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[1]     =
+                       {
+                               {
+                                       0u,                                                                     // deUint32     location;
+                                       0u,                                                                     // deUint32     binding;
+                                       VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
+                                       0u                                                                      // deUint32     offset;
+                               }
+                       };
 
-               VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
-               vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
-               vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+                       const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                          =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
+                               DE_NULL,                                                                                                        // const void*                                                          pNext;
+                               0u,                                                                                                                     // VkPipelineVertexInputStateCreateFlags        flags;
+                               1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
+                               &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
+                               1u,                                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount;
+                               vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
+                       };
 
-               const VkDeviceSize      vertexBufferOffset      = 0u;
+                       const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                        =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
+                               DE_NULL,                                                                                                                // const void*                                                          pNext;
+                               0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
+                               false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
+                       };
 
-               vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
-               vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
-               vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
+                       const VkViewport        viewport        =
+                       {
+                               0.0f,                                                                   // float        x;
+                               0.0f,                                                                   // float        y;
+                               (float)m_params.src.image.extent.width, // float        width;
+                               (float)m_params.src.image.extent.height,// float        height;
+                               0.0f,                                                                   // float        minDepth;
+                               1.0f                                                                    // float        maxDepth;
+                       };
 
-               vk.cmdEndRenderPass(*cmdBuffer);
+                       const VkRect2D          scissor         =
+                       {
+                               { 0, 0 },                                                                                                                               // VkOffset2D   offset;
+                               { m_params.src.image.extent.width, m_params.src.image.extent.height }   // VkExtent2D   extent;
+                       };
 
-               VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
-       }
+                       const VkPipelineViewportStateCreateInfo                 viewportStateParams             =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
+                               DE_NULL,                                                                                                // const void*                                                  pNext;
+                               0u,                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
+                               1u,                                                                                                             // deUint32                                                             viewportCount;
+                               &viewport,                                                                                              // const VkViewport*                                    pViewports;
+                               1u,                                                                                                             // deUint32                                                             scissorCount;
+                               &scissor                                                                                                // const VkRect2D*                                              pScissors;
+                       };
 
-       // Create fence
-       {
-               const VkFenceCreateInfo fenceParams =
-               {
-                       VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
-                       DE_NULL,                                                                // const void*                  pNext;
-                       0u                                                                              // VkFenceCreateFlags   flags;
-               };
+                       const VkPipelineRasterizationStateCreateInfo    rasterStateParams               =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
+                               DE_NULL,                                                                                                        // const void*                                                          pNext;
+                               0u,                                                                                                                     // VkPipelineRasterizationStateCreateFlags      flags;
+                               false,                                                                                                          // VkBool32                                                                     depthClampEnable;
+                               false,                                                                                                          // VkBool32                                                                     rasterizerDiscardEnable;
+                               VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
+                               VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
+                               VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
+                               VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
+                               0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
+                               0.0f,                                                                                                           // float                                                                        depthBiasClamp;
+                               0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
+                               1.0f                                                                                                            // float                                                                        lineWidth;
+                       };
 
-               fence = createFence(vk, vkDevice, &fenceParams);
-       }
+                       const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
+                               DE_NULL,                                                                                                        // const void*                                                          pNext;
+                               0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
+                               rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
+                               VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
+                               0.0f,                                                                                                           // float                                                                        minSampleShading;
+                               DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
+                               VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
+                               VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
+                       };
 
-       // Queue submit.
-       {
-               const VkQueue                           queue           = m_context.getUniversalQueue();
-               const VkSubmitInfo                      submitInfo      =
+                       const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState       =
+                       {
+                               false,                                                  // VkBool32                     blendEnable;
+                               VK_BLEND_FACTOR_ONE,                    // VkBlend                      srcBlendColor;
+                               VK_BLEND_FACTOR_ZERO,                   // VkBlend                      destBlendColor;
+                               VK_BLEND_OP_ADD,                                // VkBlendOp            blendOpColor;
+                               VK_BLEND_FACTOR_ONE,                    // VkBlend                      srcBlendAlpha;
+                               VK_BLEND_FACTOR_ZERO,                   // VkBlend                      destBlendAlpha;
+                               VK_BLEND_OP_ADD,                                // VkBlendOp            blendOpAlpha;
+                               (VK_COLOR_COMPONENT_R_BIT |
+                               VK_COLOR_COMPONENT_G_BIT |
+                               VK_COLOR_COMPONENT_B_BIT |
+                               VK_COLOR_COMPONENT_A_BIT)               // VkChannelFlags       channelWriteMask;
+                       };
+
+                       const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams   =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
+                               DE_NULL,                                                                                                        // const void*                                                                  pNext;
+                               0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
+                               false,                                                                                                          // VkBool32                                                                             logicOpEnable;
+                               VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
+                               1u,                                                                                                                     // deUint32                                                                             attachmentCount;
+                               &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
+                               { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
+                       };
+
+                       const VkGraphicsPipelineCreateInfo                      graphicsPipelineParams  =
+                       {
+                               VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
+                               DE_NULL,                                                                                        // const void*                                                                          pNext;
+                               0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
+                               2u,                                                                                                     // deUint32                                                                                     stageCount;
+                               shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
+                               &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
+                               &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
+                               DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
+                               &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
+                               &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
+                               &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
+                               DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
+                               &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
+                               DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
+                               *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
+                               *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
+                               0u,                                                                                                     // deUint32                                                                                     subpass;
+                               0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
+                               0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
+                       };
+
+                       graphicsPipeline        = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
+               }
+
+               // Create command buffer
                {
-                       VK_STRUCTURE_TYPE_SUBMIT_INFO,
-                       DE_NULL,
-                       0u,
-                       (const VkSemaphore*)DE_NULL,
-                       (const VkPipelineStageFlags*)DE_NULL,
-                       1u,
-                       &cmdBuffer.get(),
-                       0u,
-                       (const VkSemaphore*)DE_NULL,
-               };
+                       const VkCommandBufferBeginInfo cmdBufferBeginInfo =
+                       {
+                               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
+                               DE_NULL,                                                                                // const void*                                          pNext;
+                               0u,                                                                                             // VkCommandBufferUsageFlags            flags;
+                               (const VkCommandBufferInheritanceInfo*)DE_NULL,
+                       };
+
+                       const VkClearValue clearValues[1] =
+                       {
+                               makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
+                       };
+
+                       const VkRenderPassBeginInfo renderPassBeginInfo =
+                       {
+                               VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
+                               DE_NULL,                                                                                                // const void*                  pNext;
+                               *renderPass,                                                                                    // VkRenderPass                 renderPass;
+                               *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
+                               {
+                                       { 0, 0 },
+                                       { m_params.src.image.extent.width, m_params.src.image.extent.height }
+                               },                                                                                                              // VkRect2D                             renderArea;
+                               1u,                                                                                                             // deUint32                             clearValueCount;
+                               clearValues                                                                                             // const VkClearValue*  pClearValues;
+                       };
 
-               VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
-               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
-               VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
+                       VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
+                       vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+                       const VkDeviceSize      vertexBufferOffset      = 0u;
+
+                       vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
+                       vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
+                       vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
+
+                       vk.cmdEndRenderPass(*m_cmdBuffer);
+                       VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+               }
+
+               // Queue submit.
+               {
+                       const VkQueue   queue   = m_context.getUniversalQueue();
+                       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
+               }
        }
 }
 
@@ -2657,19 +3137,31 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
        const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
        const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
 
-       m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
-                                                                                                                                                               m_params.src.image.extent.width,
-                                                                                                                                                               m_params.src.image.extent.height,
-                                                                                                                                                               m_params.src.image.extent.depth));
-       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_MULTISAMPLE);
-       m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
-                                                                                                                                                                        (int)m_params.dst.image.extent.width,
-                                                                                                                                                                        (int)m_params.dst.image.extent.height,
-                                                                                                                                                                        (int)m_params.dst.image.extent.depth));
+       // upload the destination image
+       m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
+                                                                                                                                                       (int)m_params.dst.image.extent.width,
+                                                                                                                                                       (int)m_params.dst.image.extent.height,
+                                                                                                                                                       (int)m_params.dst.image.extent.depth));
        generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
+       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
+
+       m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
+                                                                                                                                       (int)m_params.src.image.extent.width,
+                                                                                                                                       (int)m_params.src.image.extent.height,
+                                                                                                                                       (int)m_params.dst.image.extent.depth));
+
+       generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
        generateExpectedResult();
 
-       uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
+       switch (m_options)
+       {
+               case COPY_MS_IMAGE_TO_MS_IMAGE:
+               case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
+                       copyMSImageToMSImage();
+                       break;
+               default:
+                       break;
+       }
 
        const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
        const VkDevice                                  vkDevice                        = m_context.getDevice();
@@ -2685,7 +3177,7 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
                {
                        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
                        DE_NULL,                                                                        // const void*                          pNext;
-                       0u,                                                                                     // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
@@ -2693,11 +3185,11 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                        m_multisampledImage.get(),                                      // VkImage                                      image;
                        {                                                                                       // VkImageSubresourceRange      subresourceRange;
-                               getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
-                               0u,                                                             // deUint32                             baseMipLevel;
-                               1u,                                                             // deUint32                             mipLevels;
-                               0u,                                                             // deUint32                             baseArraySlice;
-                               1u                                                              // deUint32                             arraySize;
+                               getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
+                               0u,                                                                     // deUint32                             baseMipLevel;
+                               1u,                                                                     // deUint32                             mipLevels;
+                               0u,                                                                     // deUint32                             baseArraySlice;
+                               getArraySize(m_params.src.image)        // deUint32                             arraySize;
                        }
                },
                // destination image
@@ -2706,17 +3198,17 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
                        DE_NULL,                                                                        // const void*                          pNext;
                        0u,                                                                                     // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                        m_destination.get(),                                            // VkImage                                      image;
                        {                                                                                       // VkImageSubresourceRange      subresourceRange;
-                               getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
-                               0u,                                                             // deUint32                             baseMipLevel;
-                               1u,                                                             // deUint32                             mipLevels;
-                               0u,                                                             // deUint32                             baseArraySlice;
-                               1u                                                              // deUint32                             arraySize;
+                               getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
+                               0u,                                                                     // deUint32                             baseMipLevel;
+                               1u,                                                                     // deUint32                             mipLevels;
+                               0u,                                                                     // deUint32                             baseArraySlice;
+                               getArraySize(m_params.dst.image)        // deUint32                             arraySize;
                        }
                },
        };
@@ -2737,7 +3229,7 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
                        0u,                                                                     // deUint32                                     baseMipLevel;
                        1u,                                                                     // deUint32                                     mipLevels;
                        0u,                                                                     // deUint32                                     baseArraySlice;
-                       1u                                                                      // deUint32                                     arraySize;
+                       getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
                }
        };
 
@@ -2754,25 +3246,9 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
        vk.cmdResolveImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data());
        vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
 
-       const VkSubmitInfo                              submitInfo                      =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
-               DE_NULL,                                                // const void*                          pNext;
-               0u,                                                             // deUint32                                     waitSemaphoreCount;
-               DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
-               (const VkPipelineStageFlags*)DE_NULL,
-               1u,                                                             // deUint32                                     commandBufferCount;
-               &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
-               0u,                                                             // deUint32                                     signalSemaphoreCount;
-               DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
-       };
-
-       VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
-       VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
-       VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
-
-       de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent);
+       de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
 
        return checkTestResult(resultTextureLevel->getAccess());
 }
@@ -2782,579 +3258,249 @@ tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAcces
        const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel->getAccess();
        const float                                                     fuzzyThreshold  = 0.01f;
 
-       if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
-               return tcu::TestStatus::fail("CopiesAndBlitting test");
+       for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
+       {
+               const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
+               const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+               if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
+                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+       }
 
        return tcu::TestStatus::pass("CopiesAndBlitting test");
 }
 
 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
 {
-       VkOffset3D srcOffset    = region.imageCopy.srcOffset;
-       VkOffset3D dstOffset    = region.imageCopy.dstOffset;
-       VkExtent3D extent               = region.imageCopy.extent;
+       VkOffset3D srcOffset    = region.imageResolve.srcOffset;
+                       srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
+       VkOffset3D dstOffset    = region.imageResolve.dstOffset;
+                       dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
+       VkExtent3D extent               = region.imageResolve.extent;
 
-       const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, extent.width, extent.height);
+       const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
        // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
        const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
-       const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, extent.width, extent.height);
+       const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
 
        tcu::copy(dstSubRegion, srcSubRegion);
 }
 
-class ResolveImageToImageTestCase : public vkt::TestCase
-{
-public:
-                                                       ResolveImageToImageTestCase     (tcu::TestContext&              testCtx,
-                                                                                                                const std::string&             name,
-                                                                                                                const std::string&             description,
-                                                                                                                const TestParams               params)
-                                                               : vkt::TestCase (testCtx, name, description)
-                                                               , m_params              (params)
-                                                       {}
-       virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
-
-       virtual TestInstance*   createInstance                          (Context&                               context) const
-                                                       {
-                                                               return new ResolveImageToImage(context, m_params);
-                                                       }
-private:
-       TestParams                              m_params;
-};
-
-void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
-{
-       programCollection.glslSources.add("vert") << glu::VertexSource(
-               "#version 310 es\n"
-               "layout (location = 0) in highp vec4 a_position;\n"
-               "void main()\n"
-               "{\n"
-               "       gl_Position = a_position;\n"
-               "}\n");
-
-
-       programCollection.glslSources.add("frag") << glu::FragmentSource(
-               "#version 310 es\n"
-               "layout (location = 0) out highp vec4 o_color;\n"
-               "void main()\n"
-               "{\n"
-               "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
-               "}\n");
-}
-
-std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
-{
-       return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
-}
-
-std::string getFormatCaseName (VkFormat format)
+void ResolveImageToImage::copyMSImageToMSImage (void)
 {
-       return de::toLower(de::toString(getFormatStr(format)).substr(10));
-}
+       const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
+       const VkDevice                                  vkDevice                        = m_context.getDevice();
+       const VkQueue                                   queue                           = m_context.getUniversalQueue();
+       const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
+       std::vector<VkImageCopy>                imageCopies;
 
-void addCopyImageTestsAllFormats (tcu::TestCaseGroup*  testCaseGroup,
-                                                                 tcu::TestContext&             testCtx,
-                                                                 TestParams&                   params)
-{
-       const VkFormat  compatibleFormats8Bit[]                 =
+       for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx)
        {
-               VK_FORMAT_R4G4_UNORM_PACK8,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8_SNORM,
-               VK_FORMAT_R8_USCALED,
-               VK_FORMAT_R8_SSCALED,
-               VK_FORMAT_R8_UINT,
-               VK_FORMAT_R8_SINT,
-               VK_FORMAT_R8_SRGB,
+               const VkImageSubresourceLayers  sourceSubresourceLayers =
+               {
+                       getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // uint32_t                             mipLevel;
+                       0u,                                                             // uint32_t                             baseArrayLayer;
+                       1u                                                              // uint32_t                             layerCount;
+               };
 
-               VK_FORMAT_LAST
-       };
-       const VkFormat  compatibleFormats16Bit[]                =
-       {
-               VK_FORMAT_R4G4B4A4_UNORM_PACK16,
-               VK_FORMAT_B4G4R4A4_UNORM_PACK16,
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_B5G6R5_UNORM_PACK16,
-               VK_FORMAT_R5G5B5A1_UNORM_PACK16,
-               VK_FORMAT_B5G5R5A1_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8_SNORM,
-               VK_FORMAT_R8G8_USCALED,
-               VK_FORMAT_R8G8_SSCALED,
-               VK_FORMAT_R8G8_UINT,
-               VK_FORMAT_R8G8_SINT,
-               VK_FORMAT_R8G8_SRGB,
-               VK_FORMAT_R16_UNORM,
-               VK_FORMAT_R16_SNORM,
-               VK_FORMAT_R16_USCALED,
-               VK_FORMAT_R16_SSCALED,
-               VK_FORMAT_R16_UINT,
-               VK_FORMAT_R16_SINT,
-               VK_FORMAT_R16_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats24Bit[]                =
-       {
-               VK_FORMAT_R8G8B8_UNORM,
-               VK_FORMAT_R8G8B8_SNORM,
-               VK_FORMAT_R8G8B8_USCALED,
-               VK_FORMAT_R8G8B8_SSCALED,
-               VK_FORMAT_R8G8B8_UINT,
-               VK_FORMAT_R8G8B8_SINT,
-               VK_FORMAT_R8G8B8_SRGB,
-               VK_FORMAT_B8G8R8_UNORM,
-               VK_FORMAT_B8G8R8_SNORM,
-               VK_FORMAT_B8G8R8_USCALED,
-               VK_FORMAT_B8G8R8_SSCALED,
-               VK_FORMAT_B8G8R8_UINT,
-               VK_FORMAT_B8G8R8_SINT,
-               VK_FORMAT_B8G8R8_SRGB,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats32Bit[]                =
-       {
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SNORM,
-               VK_FORMAT_R8G8B8A8_USCALED,
-               VK_FORMAT_R8G8B8A8_SSCALED,
-               VK_FORMAT_R8G8B8A8_UINT,
-               VK_FORMAT_R8G8B8A8_SINT,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SNORM,
-               VK_FORMAT_B8G8R8A8_USCALED,
-               VK_FORMAT_B8G8R8A8_SSCALED,
-               VK_FORMAT_B8G8R8A8_UINT,
-               VK_FORMAT_B8G8R8A8_SINT,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_USCALED_PACK32,
-               VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
-               VK_FORMAT_A8B8G8R8_UINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SINT_PACK32,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-               VK_FORMAT_A2R10G10B10_UNORM_PACK32,
-               VK_FORMAT_A2R10G10B10_SNORM_PACK32,
-               VK_FORMAT_A2R10G10B10_USCALED_PACK32,
-               VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
-               VK_FORMAT_A2R10G10B10_UINT_PACK32,
-               VK_FORMAT_A2R10G10B10_SINT_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_SNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_USCALED_PACK32,
-               VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
-               VK_FORMAT_A2B10G10R10_UINT_PACK32,
-               VK_FORMAT_A2B10G10R10_SINT_PACK32,
-               VK_FORMAT_R16G16_UNORM,
-               VK_FORMAT_R16G16_SNORM,
-               VK_FORMAT_R16G16_USCALED,
-               VK_FORMAT_R16G16_SSCALED,
-               VK_FORMAT_R16G16_UINT,
-               VK_FORMAT_R16G16_SINT,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32_SINT,
-               VK_FORMAT_R32_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats48Bit[]                =
-       {
-               VK_FORMAT_R16G16B16_UNORM,
-               VK_FORMAT_R16G16B16_SNORM,
-               VK_FORMAT_R16G16B16_USCALED,
-               VK_FORMAT_R16G16B16_SSCALED,
-               VK_FORMAT_R16G16B16_UINT,
-               VK_FORMAT_R16G16B16_SINT,
-               VK_FORMAT_R16G16B16_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats64Bit[]                =
-       {
-               VK_FORMAT_R16G16B16A16_UNORM,
-               VK_FORMAT_R16G16B16A16_SNORM,
-               VK_FORMAT_R16G16B16A16_USCALED,
-               VK_FORMAT_R16G16B16A16_SSCALED,
-               VK_FORMAT_R16G16B16A16_UINT,
-               VK_FORMAT_R16G16B16A16_SINT,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_R32G32_UINT,
-               VK_FORMAT_R32G32_SINT,
-               VK_FORMAT_R32G32_SFLOAT,
-               VK_FORMAT_R64_UINT,
-               VK_FORMAT_R64_SINT,
-               VK_FORMAT_R64_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats96Bit[]                =
-       {
-               VK_FORMAT_R32G32B32_UINT,
-               VK_FORMAT_R32G32B32_SINT,
-               VK_FORMAT_R32G32B32_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats128Bit[]               =
-       {
-               VK_FORMAT_R32G32B32A32_UINT,
-               VK_FORMAT_R32G32B32A32_SINT,
-               VK_FORMAT_R32G32B32A32_SFLOAT,
-               VK_FORMAT_R64G64_UINT,
-               VK_FORMAT_R64G64_SINT,
-               VK_FORMAT_R64G64_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats192Bit[]               =
-       {
-               VK_FORMAT_R64G64B64_UINT,
-               VK_FORMAT_R64G64B64_SINT,
-               VK_FORMAT_R64G64B64_SFLOAT,
-
-               VK_FORMAT_LAST
-        };
-       const VkFormat  compatibleFormats256Bit[]               =
-       {
-               VK_FORMAT_R64G64B64A64_UINT,
-               VK_FORMAT_R64G64B64A64_SINT,
-               VK_FORMAT_R64G64B64A64_SFLOAT,
-
-               VK_FORMAT_LAST
-       };
+               const VkImageSubresourceLayers  destinationSubresourceLayers    =
+               {
+                       getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
+                       0u,                                                             // uint32_t                             mipLevel;
+                       layerNdx,                                               // uint32_t                             baseArrayLayer;
+                       1u                                                              // uint32_t                             layerCount;
+               };
 
-       const VkFormat* colorImageFormatsToTest[]               =
-       {
-               compatibleFormats8Bit,
-               compatibleFormats16Bit,
-               compatibleFormats24Bit,
-               compatibleFormats32Bit,
-               compatibleFormats48Bit,
-               compatibleFormats64Bit,
-               compatibleFormats96Bit,
-               compatibleFormats128Bit,
-               compatibleFormats192Bit,
-               compatibleFormats256Bit,
-       };
-       const size_t    numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
+               const VkImageCopy                               imageCopy       =
+               {
+                       sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
+                       destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
+                       {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
+                        getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
+               };
+               imageCopies.push_back(imageCopy);
+       }
 
-       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
+       const VkImageMemoryBarrier              imageBarriers[]         =
        {
-               const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
-               for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_LAST; ++srcFormatIndex)
+               // source image
                {
-                       params.src.image.format = compatibleFormats[srcFormatIndex];
-                       for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_LAST; ++dstFormatIndex)
-                       {
-                               params.dst.image.format = compatibleFormats[dstFormatIndex];
-
-                               if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
-                                       continue;
-
-                               std::ostringstream      testName;
-                               testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
-                               std::ostringstream      description;
-                               description << "Copy from src " << params.src.image.format << " to dst " << params.dst.image.format;
-
-                               testCaseGroup->addChild(new CopyImageToImageTestCase(testCtx, testName.str(), description.str(), params));
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+                       m_multisampledImage.get(),                                      // VkImage                                      image;
+                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                               getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
+                               0u,                                                                     // deUint32                             baseMipLevel;
+                               1u,                                                                     // deUint32                             mipLevels;
+                               0u,                                                                     // deUint32                             baseArraySlice;
+                               getArraySize(m_params.src.image)        // deUint32                             arraySize;
                        }
-               }
-       }
-}
-
-void addBlittingTestsAllFormats (tcu::TestCaseGroup*   testCaseGroup,
-                                                                tcu::TestContext&              testCtx,
-                                                                TestParams&                    params)
-{
-       // Test Image formats.
-       const VkFormat  compatibleFormatsUInts[]                        =
-       {
-               VK_FORMAT_R8_UINT,
-               VK_FORMAT_R8G8_UINT,
-               VK_FORMAT_R8G8B8_UINT,
-               VK_FORMAT_B8G8R8_UINT,
-               VK_FORMAT_R8G8B8A8_UINT,
-               VK_FORMAT_B8G8R8A8_UINT,
-               VK_FORMAT_A8B8G8R8_UINT_PACK32,
-               VK_FORMAT_A2R10G10B10_UINT_PACK32,
-               VK_FORMAT_A2B10G10R10_UINT_PACK32,
-               VK_FORMAT_R16_UINT,
-               VK_FORMAT_R16G16_UINT,
-               VK_FORMAT_R16G16B16_UINT,
-               VK_FORMAT_R16G16B16A16_UINT,
-               VK_FORMAT_R32_UINT,
-               VK_FORMAT_R32G32_UINT,
-               VK_FORMAT_R32G32B32_UINT,
-               VK_FORMAT_R32G32B32A32_UINT,
-               VK_FORMAT_R64_UINT,
-               VK_FORMAT_R64G64_UINT,
-               VK_FORMAT_R64G64B64_UINT,
-               VK_FORMAT_R64G64B64A64_UINT,
-
-               VK_FORMAT_LAST
-       };
-       const VkFormat  compatibleFormatsSInts[]                        =
-       {
-               VK_FORMAT_R8_SINT,
-               VK_FORMAT_R8G8_SINT,
-               VK_FORMAT_R8G8B8_SINT,
-               VK_FORMAT_B8G8R8_SINT,
-               VK_FORMAT_R8G8B8A8_SINT,
-               VK_FORMAT_B8G8R8A8_SINT,
-               VK_FORMAT_A8B8G8R8_SINT_PACK32,
-               VK_FORMAT_A2R10G10B10_SINT_PACK32,
-               VK_FORMAT_A2B10G10R10_SINT_PACK32,
-               VK_FORMAT_R16_SINT,
-               VK_FORMAT_R16G16_SINT,
-               VK_FORMAT_R16G16B16_SINT,
-               VK_FORMAT_R16G16B16A16_SINT,
-               VK_FORMAT_R32_SINT,
-               VK_FORMAT_R32G32_SINT,
-               VK_FORMAT_R32G32B32_SINT,
-               VK_FORMAT_R32G32B32A32_SINT,
-               VK_FORMAT_R64_SINT,
-               VK_FORMAT_R64G64_SINT,
-               VK_FORMAT_R64G64B64_SINT,
-               VK_FORMAT_R64G64B64A64_SINT,
-
-               VK_FORMAT_LAST
-       };
-       const VkFormat  compatibleFormatsFloats[]                       =
-       {
-               VK_FORMAT_R4G4_UNORM_PACK8,
-               VK_FORMAT_R4G4B4A4_UNORM_PACK16,
-               VK_FORMAT_B4G4R4A4_UNORM_PACK16,
-               VK_FORMAT_R5G6B5_UNORM_PACK16,
-               VK_FORMAT_B5G6R5_UNORM_PACK16,
-               VK_FORMAT_R5G5B5A1_UNORM_PACK16,
-               VK_FORMAT_B5G5R5A1_UNORM_PACK16,
-               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
-               VK_FORMAT_R8_UNORM,
-               VK_FORMAT_R8_SNORM,
-               VK_FORMAT_R8_USCALED,
-               VK_FORMAT_R8_SSCALED,
-               VK_FORMAT_R8G8_UNORM,
-               VK_FORMAT_R8G8_SNORM,
-               VK_FORMAT_R8G8_USCALED,
-               VK_FORMAT_R8G8_SSCALED,
-               VK_FORMAT_R8G8B8_UNORM,
-               VK_FORMAT_R8G8B8_SNORM,
-               VK_FORMAT_R8G8B8_USCALED,
-               VK_FORMAT_R8G8B8_SSCALED,
-               VK_FORMAT_B8G8R8_UNORM,
-               VK_FORMAT_B8G8R8_SNORM,
-               VK_FORMAT_B8G8R8_USCALED,
-               VK_FORMAT_B8G8R8_SSCALED,
-               VK_FORMAT_R8G8B8A8_UNORM,
-               VK_FORMAT_R8G8B8A8_SNORM,
-               VK_FORMAT_R8G8B8A8_USCALED,
-               VK_FORMAT_R8G8B8A8_SSCALED,
-               VK_FORMAT_B8G8R8A8_UNORM,
-               VK_FORMAT_B8G8R8A8_SNORM,
-               VK_FORMAT_B8G8R8A8_USCALED,
-               VK_FORMAT_B8G8R8A8_SSCALED,
-               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_SNORM_PACK32,
-               VK_FORMAT_A8B8G8R8_USCALED_PACK32,
-               VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
-               VK_FORMAT_A2R10G10B10_UNORM_PACK32,
-               VK_FORMAT_A2R10G10B10_SNORM_PACK32,
-               VK_FORMAT_A2R10G10B10_USCALED_PACK32,
-               VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
-               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_SNORM_PACK32,
-               VK_FORMAT_A2B10G10R10_USCALED_PACK32,
-               VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
-               VK_FORMAT_R16_UNORM,
-               VK_FORMAT_R16_SNORM,
-               VK_FORMAT_R16_USCALED,
-               VK_FORMAT_R16_SSCALED,
-               VK_FORMAT_R16_SFLOAT,
-               VK_FORMAT_R16G16_UNORM,
-               VK_FORMAT_R16G16_SNORM,
-               VK_FORMAT_R16G16_USCALED,
-               VK_FORMAT_R16G16_SSCALED,
-               VK_FORMAT_R16G16_SFLOAT,
-               VK_FORMAT_R16G16B16_UNORM,
-               VK_FORMAT_R16G16B16_SNORM,
-               VK_FORMAT_R16G16B16_USCALED,
-               VK_FORMAT_R16G16B16_SSCALED,
-               VK_FORMAT_R16G16B16_SFLOAT,
-               VK_FORMAT_R16G16B16A16_UNORM,
-               VK_FORMAT_R16G16B16A16_SNORM,
-               VK_FORMAT_R16G16B16A16_USCALED,
-               VK_FORMAT_R16G16B16A16_SSCALED,
-               VK_FORMAT_R16G16B16A16_SFLOAT,
-               VK_FORMAT_R32_SFLOAT,
-               VK_FORMAT_R32G32_SFLOAT,
-               VK_FORMAT_R32G32B32_SFLOAT,
-               VK_FORMAT_R32G32B32A32_SFLOAT,
-               VK_FORMAT_R64_SFLOAT,
-               VK_FORMAT_R64G64_SFLOAT,
-               VK_FORMAT_R64G64B64_SFLOAT,
-               VK_FORMAT_R64G64B64A64_SFLOAT,
-//             VK_FORMAT_B10G11R11_UFLOAT_PACK32,
-//             VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
-//             VK_FORMAT_BC1_RGB_UNORM_BLOCK,
-//             VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
-//             VK_FORMAT_BC2_UNORM_BLOCK,
-//             VK_FORMAT_BC3_UNORM_BLOCK,
-//             VK_FORMAT_BC4_UNORM_BLOCK,
-//             VK_FORMAT_BC4_SNORM_BLOCK,
-//             VK_FORMAT_BC5_UNORM_BLOCK,
-//             VK_FORMAT_BC5_SNORM_BLOCK,
-//             VK_FORMAT_BC6H_UFLOAT_BLOCK,
-//             VK_FORMAT_BC6H_SFLOAT_BLOCK,
-//             VK_FORMAT_BC7_UNORM_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
-//             VK_FORMAT_EAC_R11_UNORM_BLOCK,
-//             VK_FORMAT_EAC_R11_SNORM_BLOCK,
-//             VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
-//             VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
-//             VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
-//             VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
-
-               VK_FORMAT_LAST
-       };
-       const VkFormat  compatibleFormatsSrgb[]                         =
-       {
-               VK_FORMAT_R8_SRGB,
-               VK_FORMAT_R8G8_SRGB,
-               VK_FORMAT_R8G8B8_SRGB,
-               VK_FORMAT_B8G8R8_SRGB,
-               VK_FORMAT_R8G8B8A8_SRGB,
-               VK_FORMAT_B8G8R8A8_SRGB,
-               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
-//             VK_FORMAT_BC1_RGB_SRGB_BLOCK,
-//             VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
-//             VK_FORMAT_BC2_SRGB_BLOCK,
-//             VK_FORMAT_BC3_SRGB_BLOCK,
-//             VK_FORMAT_BC7_SRGB_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
-//             VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
-//             VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
-
-               VK_FORMAT_LAST
+               },
+               // destination image
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0,                                                                                      // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+                       m_multisampledCopyImage.get(),                          // VkImage                                      image;
+                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                               getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
+                               0u,                                                                     // deUint32                             baseMipLevel;
+                               1u,                                                                     // deUint32                             mipLevels;
+                               0u,                                                                     // deUint32                             baseArraySlice;
+                               getArraySize(m_params.dst.image)        // deUint32                             arraySize;
+                       }
+               },
        };
 
-       const struct {
-               const VkFormat* compatibleFormats;
-               const bool              onlyNearest;
-       }       colorImageFormatsToTest[]                       =
+       const VkImageMemoryBarrier      postImageBarriers               =
+       // source image
        {
-               { compatibleFormatsUInts,       true    },
-               { compatibleFormatsSInts,       true    },
-               { compatibleFormatsFloats,      false   },
-               { compatibleFormatsSrgb,        false   },
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+               DE_NULL,                                                                        // const void*                          pNext;
+               VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
+               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+               m_multisampledCopyImage.get(),                          // VkImage                                      image;
+               {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                       getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
+                       0u,                                                                     // deUint32                             baseMipLevel;
+                       1u,                                                                     // deUint32                             mipLevels;
+                       0u,                                                                     // deUint32                             baseArraySlice;
+                       getArraySize(m_params.dst.image)        // deUint32                             arraySize;
+               }
        };
-       const size_t    numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
 
-       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
+       const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
        {
-               const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats;
-               const bool              onlyNearest                     = colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest;
-               for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_LAST; ++srcFormatIndex)
-               {
-                       params.src.image.format = compatibleFormats[srcFormatIndex];
-                       for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_LAST; ++dstFormatIndex)
-                       {
-                               params.dst.image.format = compatibleFormats[dstFormatIndex];
-
-                               if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
-                                       continue;
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
+               DE_NULL,                                                                                                // const void*                                          pNext;
+               VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
+               (const VkCommandBufferInheritanceInfo*)DE_NULL,
+       };
 
-                               std::ostringstream      testName;
-                               testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
-                               std::ostringstream      description;
-                               description << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format;
+       VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
+       vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data());
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
+       VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
 
-                               params.filter                   = VK_FILTER_NEAREST;
-                               testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params));
+       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
 
-                               if (!onlyNearest)
-                               {
-                                       params.filter           = VK_FILTER_LINEAR;
-                                       testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params));
-                               }
-                       }
-               }
-       }
+       m_multisampledImage = m_multisampledCopyImage;
 }
 
-} // anonymous
-
-tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
+class ResolveImageToImageTestCase : public vkt::TestCase
 {
-       de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests  (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
+public:
+                                                       ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
+                                                                                                                const std::string&                                     name,
+                                                                                                                const std::string&                                     description,
+                                                                                                                const TestParams                                       params,
+                                                                                                                const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
+                                                               : vkt::TestCase (testCtx, name, description)
+                                                               , m_params              (params)
+                                                               , m_options             (options)
+                                                       {}
+       virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
+
+       virtual TestInstance*   createInstance                          (Context&                               context) const
+                                                       {
+                                                               return new ResolveImageToImage(context, m_params, m_options);
+                                                       }
+private:
+       TestParams                                                      m_params;
+       const ResolveImageToImageOptions        m_options;
+};
 
-       de::MovePtr<tcu::TestCaseGroup> imageToImageTests               (new tcu::TestCaseGroup(testCtx, "image_to_image", "Copy from image to image"));
-       de::MovePtr<tcu::TestCaseGroup> imgToImgSimpleTests             (new tcu::TestCaseGroup(testCtx, "simple_tests", "Copy from image to image simple tests"));
-       de::MovePtr<tcu::TestCaseGroup> imgToImgAllFormatsTests (new tcu::TestCaseGroup(testCtx, "all_formats", "Copy from image to image with all compatible formats"));
+void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
+{
+       programCollection.glslSources.add("vert") << glu::VertexSource(
+               "#version 310 es\n"
+               "layout (location = 0) in highp vec4 a_position;\n"
+               "void main()\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "}\n");
 
-       de::MovePtr<tcu::TestCaseGroup> imageToBufferTests              (new tcu::TestCaseGroup(testCtx, "image_to_buffer", "Copy from image to buffer"));
-       de::MovePtr<tcu::TestCaseGroup> bufferToImageTests              (new tcu::TestCaseGroup(testCtx, "buffer_to_image", "Copy from buffer to image"));
-       de::MovePtr<tcu::TestCaseGroup> bufferToBufferTests             (new tcu::TestCaseGroup(testCtx, "buffer_to_buffer", "Copy from buffer to buffer"));
 
-       de::MovePtr<tcu::TestCaseGroup> blittingImageTests              (new tcu::TestCaseGroup(testCtx, "blit_image", "Blitting image"));
-       de::MovePtr<tcu::TestCaseGroup> blitImgSimpleTests              (new tcu::TestCaseGroup(testCtx, "simple_tests", "Blitting image simple tests"));
-       de::MovePtr<tcu::TestCaseGroup> blitImgAllFormatsTests  (new tcu::TestCaseGroup(testCtx, "all_formats", "Blitting image with all compatible formats"));
+       programCollection.glslSources.add("frag") << glu::FragmentSource(
+               "#version 310 es\n"
+               "layout (location = 0) out highp vec4 o_color;\n"
+               "void main()\n"
+               "{\n"
+               "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+               "}\n");
+}
 
-       de::MovePtr<tcu::TestCaseGroup> resolveImageTests               (new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image"));
+std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
+{
+       return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
+}
 
-       const deInt32                                   defaultSize                             = 64;
-       const deInt32                                   defaultHalfSize                 = defaultSize / 2;
-       const deInt32                                   defaultFourthSize               = defaultSize / 4;
-       const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
-       const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
+std::string getFormatCaseName (VkFormat format)
+{
+       return de::toLower(de::toString(getFormatStr(format)).substr(10));
+}
 
-       const VkImageSubresourceLayers  defaultSourceLayer              =
+std::string getImageLayoutCaseName (VkImageLayout layout)
+{
+       switch (layout)
        {
-               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
-               0u,                                                     // uint32_t                             mipLevel;
-               0u,                                                     // uint32_t                             baseArrayLayer;
-               1u,                                                     // uint32_t                             layerCount;
-       };
+               case VK_IMAGE_LAYOUT_GENERAL:
+                       return "general";
+               case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
+               case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
+                       return "optimal";
+               default:
+                       DE_ASSERT(false);
+                       return "";
+       }
+}
+
+const deInt32                                  defaultSize                             = 64;
+const deInt32                                  defaultHalfSize                 = defaultSize / 2;
+const deInt32                                  defaultFourthSize               = defaultSize / 4;
+const VkExtent3D                               defaultExtent                   = {defaultSize, defaultSize, 1};
+const VkExtent3D                               defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
+
+const VkImageSubresourceLayers defaultSourceLayer              =
+{
+       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+       0u,                                                     // uint32_t                             mipLevel;
+       0u,                                                     // uint32_t                             baseArrayLayer;
+       1u,                                                     // uint32_t                             layerCount;
+};
+
+void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx       = group->getTestContext();
 
-       // Copy image to image testcases.
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.dst.image.extent = defaultExtent;
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
 
                {
                        const VkImageCopy                               testCopy        =
@@ -3372,15 +3518,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(imageCopy);
                }
 
-               imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
+               group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
        }
 
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.format = VK_FORMAT_R32_UINT;
-               params.dst.image.extent = defaultExtent;
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R32_UINT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
 
                {
                        const VkImageCopy                               testCopy        =
@@ -3398,15 +3549,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(imageCopy);
                }
 
-               imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
+               group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
        }
 
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.dst.image.extent = defaultExtent;
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
 
                {
                        const VkImageCopy                               testCopy        =
@@ -3424,15 +3580,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(imageCopy);
                }
 
-               imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
+               group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
        }
 
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_D32_SFLOAT;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.format = VK_FORMAT_D32_SFLOAT;
-               params.dst.image.extent = defaultExtent;
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_D32_SFLOAT;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_D32_SFLOAT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
 
                {
                        const VkImageSubresourceLayers  sourceLayer =
@@ -3457,15 +3618,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(imageCopy);
                }
 
-               imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
+               group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
        }
 
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_S8_UINT;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.format = VK_FORMAT_S8_UINT;
-               params.dst.image.extent = defaultExtent;
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_S8_UINT;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_S8_UINT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
 
                {
                        const VkImageSubresourceLayers  sourceLayer =
@@ -3490,133 +3656,1031 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(imageCopy);
                }
 
-               imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
+               group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
        }
+}
+
+struct CopyColorTestParams
+{
+       TestParams              params;
+       const VkFormat* compatibleFormats;
+};
 
+void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
+{
+       const VkImageLayout copySrcLayouts[]            =
        {
-               TestParams                      params;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.extent = defaultExtent;
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout copyDstLayouts[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
 
-               for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
-               {
-                       const VkImageCopy                               testCopy        =
-                       {
-                               defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
-                               {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
-                               defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
-                               {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
-                               {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
-                       };
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
+       {
+               params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
 
-                       CopyRegion      imageCopy;
-                       imageCopy.imageCopy     = testCopy;
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
+               {
+                       params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
 
-                       params.regions.push_back(imageCopy);
+                       const std::string testName      = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
+                                                                                 getImageLayoutCaseName(params.dst.image.operationLayout);
+                       const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
+                                                                                         " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
+                       group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
                }
-
-               addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params);
        }
-       imageToImageTests->addChild(imgToImgSimpleTests.release());
-       imageToImageTests->addChild(imgToImgAllFormatsTests.release());
+}
+
+bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams)
+{
+       bool result = true;
 
-       // Copy image to buffer testcases.
+       if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
        {
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent = defaultExtent;
-               params.dst.buffer.size  = defaultSize * defaultSize;
+               DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
 
-               const VkBufferImageCopy                 bufferImageCopy =
-               {
-                       0u,                                                                                     // VkDeviceSize                         bufferOffset;
-                       0u,                                                                                     // uint32_t                                     bufferRowLength;
-                       0u,                                                                                     // uint32_t                                     bufferImageHeight;
-                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
-                       {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
-                       {defaultFourthSize, defaultFourthSize, 1}       // VkExtent3D                           imageExtent;
-               };
-               CopyRegion      copyRegion;
-               copyRegion.bufferImageCopy      = bufferImageCopy;
+               result =
+                       de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
+                       de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
+       }
 
-               params.regions.push_back(copyRegion);
+       return result;
+}
+
+void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
+{
+       for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
+       {
+               testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
+               if (!isSupportedByFramework(testParams.params.dst.image.format))
+                       continue;
+
+               if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
+                       continue;
 
-               imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
+               const std::string description   = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
+               addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
        }
+}
 
-       // Copy buffer to image testcases.
-       {
-               TestParams                      params;
-               params.src.buffer.size  = defaultSize * defaultSize;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
-               params.dst.image.extent = defaultExtent;
+const VkFormat compatibleFormats8Bit[]         =
+{
+       VK_FORMAT_R4G4_UNORM_PACK8,
+       VK_FORMAT_R8_UNORM,
+       VK_FORMAT_R8_SNORM,
+       VK_FORMAT_R8_USCALED,
+       VK_FORMAT_R8_SSCALED,
+       VK_FORMAT_R8_UINT,
+       VK_FORMAT_R8_SINT,
+       VK_FORMAT_R8_SRGB,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats16Bit[]        =
+{
+       VK_FORMAT_R4G4B4A4_UNORM_PACK16,
+       VK_FORMAT_B4G4R4A4_UNORM_PACK16,
+       VK_FORMAT_R5G6B5_UNORM_PACK16,
+       VK_FORMAT_B5G6R5_UNORM_PACK16,
+       VK_FORMAT_R5G5B5A1_UNORM_PACK16,
+       VK_FORMAT_B5G5R5A1_UNORM_PACK16,
+       VK_FORMAT_A1R5G5B5_UNORM_PACK16,
+       VK_FORMAT_R8G8_UNORM,
+       VK_FORMAT_R8G8_SNORM,
+       VK_FORMAT_R8G8_USCALED,
+       VK_FORMAT_R8G8_SSCALED,
+       VK_FORMAT_R8G8_UINT,
+       VK_FORMAT_R8G8_SINT,
+       VK_FORMAT_R8G8_SRGB,
+       VK_FORMAT_R16_UNORM,
+       VK_FORMAT_R16_SNORM,
+       VK_FORMAT_R16_USCALED,
+       VK_FORMAT_R16_SSCALED,
+       VK_FORMAT_R16_UINT,
+       VK_FORMAT_R16_SINT,
+       VK_FORMAT_R16_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats24Bit[]        =
+{
+       VK_FORMAT_R8G8B8_UNORM,
+       VK_FORMAT_R8G8B8_SNORM,
+       VK_FORMAT_R8G8B8_USCALED,
+       VK_FORMAT_R8G8B8_SSCALED,
+       VK_FORMAT_R8G8B8_UINT,
+       VK_FORMAT_R8G8B8_SINT,
+       VK_FORMAT_R8G8B8_SRGB,
+       VK_FORMAT_B8G8R8_UNORM,
+       VK_FORMAT_B8G8R8_SNORM,
+       VK_FORMAT_B8G8R8_USCALED,
+       VK_FORMAT_B8G8R8_SSCALED,
+       VK_FORMAT_B8G8R8_UINT,
+       VK_FORMAT_B8G8R8_SINT,
+       VK_FORMAT_B8G8R8_SRGB,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats32Bit[]        =
+{
+       VK_FORMAT_R8G8B8A8_UNORM,
+       VK_FORMAT_R8G8B8A8_SNORM,
+       VK_FORMAT_R8G8B8A8_USCALED,
+       VK_FORMAT_R8G8B8A8_SSCALED,
+       VK_FORMAT_R8G8B8A8_UINT,
+       VK_FORMAT_R8G8B8A8_SINT,
+       VK_FORMAT_R8G8B8A8_SRGB,
+       VK_FORMAT_B8G8R8A8_UNORM,
+       VK_FORMAT_B8G8R8A8_SNORM,
+       VK_FORMAT_B8G8R8A8_USCALED,
+       VK_FORMAT_B8G8R8A8_SSCALED,
+       VK_FORMAT_B8G8R8A8_UINT,
+       VK_FORMAT_B8G8R8A8_SINT,
+       VK_FORMAT_B8G8R8A8_SRGB,
+       VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+       VK_FORMAT_A8B8G8R8_SNORM_PACK32,
+       VK_FORMAT_A8B8G8R8_USCALED_PACK32,
+       VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
+       VK_FORMAT_A8B8G8R8_UINT_PACK32,
+       VK_FORMAT_A8B8G8R8_SINT_PACK32,
+       VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+       VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+       VK_FORMAT_A2R10G10B10_SNORM_PACK32,
+       VK_FORMAT_A2R10G10B10_USCALED_PACK32,
+       VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
+       VK_FORMAT_A2R10G10B10_UINT_PACK32,
+       VK_FORMAT_A2R10G10B10_SINT_PACK32,
+       VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+       VK_FORMAT_A2B10G10R10_SNORM_PACK32,
+       VK_FORMAT_A2B10G10R10_USCALED_PACK32,
+       VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
+       VK_FORMAT_A2B10G10R10_UINT_PACK32,
+       VK_FORMAT_A2B10G10R10_SINT_PACK32,
+       VK_FORMAT_R16G16_UNORM,
+       VK_FORMAT_R16G16_SNORM,
+       VK_FORMAT_R16G16_USCALED,
+       VK_FORMAT_R16G16_SSCALED,
+       VK_FORMAT_R16G16_UINT,
+       VK_FORMAT_R16G16_SINT,
+       VK_FORMAT_R16G16_SFLOAT,
+       VK_FORMAT_R32_UINT,
+       VK_FORMAT_R32_SINT,
+       VK_FORMAT_R32_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats48Bit[]        =
+{
+       VK_FORMAT_R16G16B16_UNORM,
+       VK_FORMAT_R16G16B16_SNORM,
+       VK_FORMAT_R16G16B16_USCALED,
+       VK_FORMAT_R16G16B16_SSCALED,
+       VK_FORMAT_R16G16B16_UINT,
+       VK_FORMAT_R16G16B16_SINT,
+       VK_FORMAT_R16G16B16_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats64Bit[]        =
+{
+       VK_FORMAT_R16G16B16A16_UNORM,
+       VK_FORMAT_R16G16B16A16_SNORM,
+       VK_FORMAT_R16G16B16A16_USCALED,
+       VK_FORMAT_R16G16B16A16_SSCALED,
+       VK_FORMAT_R16G16B16A16_UINT,
+       VK_FORMAT_R16G16B16A16_SINT,
+       VK_FORMAT_R16G16B16A16_SFLOAT,
+       VK_FORMAT_R32G32_UINT,
+       VK_FORMAT_R32G32_SINT,
+       VK_FORMAT_R32G32_SFLOAT,
+       VK_FORMAT_R64_UINT,
+       VK_FORMAT_R64_SINT,
+       VK_FORMAT_R64_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats96Bit[]        =
+{
+       VK_FORMAT_R32G32B32_UINT,
+       VK_FORMAT_R32G32B32_SINT,
+       VK_FORMAT_R32G32B32_SFLOAT,
 
-               const VkBufferImageCopy                 bufferImageCopy =
-               {
-                       0u,                                                                                     // VkDeviceSize                         bufferOffset;
-                       0u,                                                                                     // uint32_t                                     bufferRowLength;
-                       0u,                                                                                     // uint32_t                                     bufferImageHeight;
-                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
-                       {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
-                       {defaultFourthSize, defaultFourthSize, 1}       // VkExtent3D                           imageExtent;
-               };
-               CopyRegion      copyRegion;
-               copyRegion.bufferImageCopy      = bufferImageCopy;
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats128Bit[]       =
+{
+       VK_FORMAT_R32G32B32A32_UINT,
+       VK_FORMAT_R32G32B32A32_SINT,
+       VK_FORMAT_R32G32B32A32_SFLOAT,
+       VK_FORMAT_R64G64_UINT,
+       VK_FORMAT_R64G64_SINT,
+       VK_FORMAT_R64G64_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats192Bit[]       =
+{
+       VK_FORMAT_R64G64B64_UINT,
+       VK_FORMAT_R64G64B64_SINT,
+       VK_FORMAT_R64G64B64_SFLOAT,
 
-               params.regions.push_back(copyRegion);
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats256Bit[]       =
+{
+       VK_FORMAT_R64G64B64A64_UINT,
+       VK_FORMAT_R64G64B64A64_SINT,
+       VK_FORMAT_R64G64B64A64_SFLOAT,
 
-               bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
-       }
+       VK_FORMAT_UNDEFINED
+};
 
-       // Copy buffer to buffer testcases.
-       {
-               TestParams                      params;
-               params.src.buffer.size  = defaultSize;
-               params.dst.buffer.size  = defaultSize;
+const VkFormat*        colorImageFormatsToTest[]       =
+{
+       compatibleFormats8Bit,
+       compatibleFormats16Bit,
+       compatibleFormats24Bit,
+       compatibleFormats32Bit,
+       compatibleFormats48Bit,
+       compatibleFormats64Bit,
+       compatibleFormats96Bit,
+       compatibleFormats128Bit,
+       compatibleFormats192Bit,
+       compatibleFormats256Bit,
+};
 
-               const VkBufferCopy      bufferCopy      =
+const VkFormat dedicatedAllocationImageToImageFormatsToTest[]  =
+{
+       // From compatibleFormats8Bit
+       VK_FORMAT_R4G4_UNORM_PACK8,
+       VK_FORMAT_R8_SRGB,
+
+       // From compatibleFormats16Bit
+       VK_FORMAT_R4G4B4A4_UNORM_PACK16,
+       VK_FORMAT_R16_SFLOAT,
+
+       // From compatibleFormats24Bit
+       VK_FORMAT_R8G8B8_UNORM,
+       VK_FORMAT_B8G8R8_SRGB,
+
+       // From compatibleFormats32Bit
+       VK_FORMAT_R8G8B8A8_UNORM,
+       VK_FORMAT_R32_SFLOAT,
+
+       // From compatibleFormats48Bit
+       VK_FORMAT_R16G16B16_UNORM,
+       VK_FORMAT_R16G16B16_SFLOAT,
+
+       // From compatibleFormats64Bit
+       VK_FORMAT_R16G16B16A16_UNORM,
+       VK_FORMAT_R64_SFLOAT,
+
+       // From compatibleFormats96Bit
+       VK_FORMAT_R32G32B32_UINT,
+       VK_FORMAT_R32G32B32_SFLOAT,
+
+       // From compatibleFormats128Bit
+       VK_FORMAT_R32G32B32A32_UINT,
+       VK_FORMAT_R64G64_SFLOAT,
+
+       // From compatibleFormats192Bit
+       VK_FORMAT_R64G64B64_UINT,
+       VK_FORMAT_R64G64B64_SFLOAT,
+
+       // From compatibleFormats256Bit
+       VK_FORMAT_R64G64B64A64_UINT,
+       VK_FORMAT_R64G64B64A64_SFLOAT,
+};
+
+void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType      = VK_IMAGE_TYPE_2D;
+       params.src.image.extent         = defaultExtent;
+       params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent         = defaultExtent;
+       params.allocationKind           = allocationKind;
+
+       for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
+       {
+               const VkImageCopy                               testCopy =
                {
-                       0u,                             // VkDeviceSize srcOffset;
-                       0u,                             // VkDeviceSize dstOffset;
-                       defaultSize,    // VkDeviceSize size;
+                       defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
+                       defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
+                       {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
+                       {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
                };
 
-               CopyRegion      copyRegion;
-               copyRegion.bufferCopy   = bufferCopy;
-               params.regions.push_back(copyRegion);
+               CopyRegion      imageCopy;
+               imageCopy.imageCopy = testCopy;
 
-               bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
+               params.regions.push_back(imageCopy);
        }
 
+       if (allocationKind == ALLOCATION_KIND_DEDICATED)
        {
-               TestParams                      params;
-               params.src.buffer.size  = defaultFourthSize;
-               params.dst.buffer.size  = defaultFourthSize;
+               const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
+               for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
+                       dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
+       }
 
-               const VkBufferCopy      bufferCopy      =
+       const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
+       for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
+       {
+               const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
+               for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
                {
-                       12u,    // VkDeviceSize srcOffset;
-                       4u,             // VkDeviceSize dstOffset;
-                       1u,             // VkDeviceSize size;
-               };
+                       params.src.image.format = compatibleFormats[srcFormatIndex];
+                       if (!isSupportedByFramework(params.src.image.format))
+                               continue;
 
-               CopyRegion      copyRegion;
-               copyRegion.bufferCopy = bufferCopy;
-               params.regions.push_back(copyRegion);
+                       CopyColorTestParams     testParams;
+                       testParams.params                               = params;
+                       testParams.compatibleFormats    = compatibleFormats;
 
-               bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
+                       const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
+                       addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
+               }
        }
+}
 
+void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
+{
+       const VkImageLayout copySrcLayouts[]            =
        {
-               const deUint32          size            = 16;
-               TestParams                      params;
-               params.src.buffer.size  = size;
-               params.dst.buffer.size  = size * (size + 1);
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout copyDstLayouts[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
 
-               // Copy region with size 1..size
-               for (unsigned int i = 1; i <= size; i++)
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
+       {
+               params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
                {
-                       const VkBufferCopy      bufferCopy      =
+                       params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
+
+                       const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
+                                                                                         getImageLayoutCaseName(params.dst.image.operationLayout);
+                       const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
+                                                                                         " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
+                       group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
+               }
+       }
+}
+
+void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       const VkFormat  depthAndStencilFormats[]        =
+       {
+               VK_FORMAT_D16_UNORM,
+               VK_FORMAT_X8_D24_UNORM_PACK32,
+               VK_FORMAT_D32_SFLOAT,
+               VK_FORMAT_S8_UINT,
+               VK_FORMAT_D16_UNORM_S8_UINT,
+               VK_FORMAT_D24_UNORM_S8_UINT,
+               VK_FORMAT_D32_SFLOAT_S8_UINT,
+       };
+
+       for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
+       {
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.extent                         = defaultExtent;
+               params.dst.image.extent                         = defaultExtent;
+               params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
+               params.dst.image.format                         = params.src.image.format;
+               params.allocationKind                           = allocationKind;
+
+               const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
+               const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
+
+               for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
+               {
+                       CopyRegion                      copyRegion;
+                       const VkOffset3D        srcOffset       = {0, 0, 0};
+                       const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
+                       const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
+
+                       if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
+                       {
+                               const VkImageCopy                               testCopy        =
+                               {
+                                       defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
+                                       srcOffset,                                      // VkOffset3D                           srcOffset;
+                                       defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
+                                       dstOffset,                                      // VkOffset3D                           dstOffset;
+                                       extent,                                         // VkExtent3D                           extent;
+                               };
+
+                               copyRegion.imageCopy    = testCopy;
+                               params.regions.push_back(copyRegion);
+                       }
+                       if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
+                       {
+                               const VkImageCopy                               testCopy        =
+                               {
+                                       defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
+                                       srcOffset,                                      // VkOffset3D                           srcOffset;
+                                       defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
+                                       dstOffset,                                      // VkOffset3D                           dstOffset;
+                                       extent,                                         // VkExtent3D                           extent;
+                               };
+
+                               copyRegion.imageCopy    = testCopy;
+                               params.regions.push_back(copyRegion);
+                       }
+               }
+
+               const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
+               const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
+               addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
+       }
+}
+
+void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind);
+       addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind);
+}
+
+void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx       = group->getTestContext();
+
+       {
+               TestParams      params3DTo2D;
+               const deUint32  slicesLayers                    = 16u;
+               params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
+               params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.src.image.extent                   = defaultHalfExtent;
+               params3DTo2D.src.image.extent.depth             = slicesLayers;
+               params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
+               params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.dst.image.extent                   = defaultHalfExtent;
+               params3DTo2D.dst.image.extent.depth             = slicesLayers;
+               params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params3DTo2D.allocationKind                             = allocationKind;
+
+               for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
+                               {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                                   srcOffset;
+                               destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
+                               {0, 0, 0},                                                      // VkOffset3D                                   dstOffset;
+                               defaultHalfExtent,                                      // VkExtent3D                                   extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy     = testCopy;
+
+                       params3DTo2D.regions.push_back(imageCopy);
+               }
+               group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
+       }
+
+       {
+               TestParams      params2DTo3D;
+               const deUint32  slicesLayers                    = 16u;
+               params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
+               params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.src.image.extent                   = defaultHalfExtent;
+               params2DTo3D.src.image.extent.depth             = slicesLayers;
+               params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
+               params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.dst.image.extent                   = defaultHalfExtent;
+               params2DTo3D.dst.image.extent.depth             = slicesLayers;
+               params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params2DTo3D.allocationKind                             = allocationKind;
+
+               for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
+                               {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
+                               destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
+                               {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           dstOffset;
+                               defaultHalfExtent,                                      // VkExtent3D                           extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy     = testCopy;
+
+                       params2DTo3D.regions.push_back(imageCopy);
+               }
+
+               group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
+       }
+
+       {
+               TestParams      params3DTo2D;
+               const deUint32  slicesLayers                    = 16u;
+               params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
+               params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.src.image.extent                   = defaultHalfExtent;
+               params3DTo2D.src.image.extent.depth             = slicesLayers;
+               params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
+               params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.dst.image.extent                   = defaultHalfExtent;
+               params3DTo2D.dst.image.extent.depth             = slicesLayers;
+               params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params3DTo2D.allocationKind                             = allocationKind;
+
+               for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0,                                                      // uint32_t                             baseArrayLayer;
+                               slicesLayers                            // uint32_t                             layerCount;
+                       };
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
+                               {0, 0, 0},                                              // VkOffset3D                           srcOffset;
+                               destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
+                               {0, 0, 0},                                              // VkOffset3D                           dstOffset;
+                               params3DTo2D.src.image.extent   // VkExtent3D                           extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy     = testCopy;
+
+                       params3DTo2D.regions.push_back(imageCopy);
+               }
+               group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
+       }
+
+       {
+               TestParams      params2DTo3D;
+               const deUint32  slicesLayers                    = 16u;
+               params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
+               params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.src.image.extent                   = defaultHalfExtent;
+               params2DTo3D.src.image.extent.depth             = slicesLayers;
+               params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
+               params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.dst.image.extent                   = defaultHalfExtent;
+               params2DTo3D.dst.image.extent.depth             = slicesLayers;
+               params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params2DTo3D.allocationKind                             = allocationKind;
+
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               slicesLayers                            // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
+                               {0, 0, 0},                                              // VkOffset3D                           srcOffset;
+                               destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
+                               {0, 0, 0},                                              // VkOffset3D                           dstOffset;
+                               params2DTo3D.dst.image.extent,  // VkExtent3D                           extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy     = testCopy;
+
+                       params2DTo3D.regions.push_back(imageCopy);
+               }
+
+               group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
+       }
+
+       {
+               TestParams      params3DTo2D;
+               const deUint32  slicesLayers                    = 16u;
+               params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
+               params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.src.image.extent                   = defaultHalfExtent;
+               params3DTo2D.src.image.extent.depth             = slicesLayers;
+               params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
+               params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params3DTo2D.dst.image.extent                   = defaultHalfExtent;
+               params3DTo2D.dst.image.extent.depth             = slicesLayers;
+               params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params3DTo2D.allocationKind                             = allocationKind;
+
+               const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
+               const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
+
+               for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                                       VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
+                                       0u,                                                             // uint32_t                             mipLevel;
+                                       slicesLayersNdx,                                // uint32_t                             baseArrayLayer;
+                                       1u                                                              // uint32_t                             layerCount;
+                       };
+
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                                                                                                    // VkImageSubresourceLayers     srcSubresource;
+                               {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D                           srcOffset;
+                                       destinationLayer,                                                                                                       // VkImageSubresourceLayers     dstSubresource;
+                                       {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                         // VkOffset3D                           dstOffset;
+                                       {
+                                               (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
+                                               (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
+                                               1
+                                       }                                                                                                                                       // VkExtent3D                           extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy = testCopy;
+                       params3DTo2D.regions.push_back(imageCopy);
+               }
+               group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
+       }
+
+       {
+               TestParams      params2DTo3D;
+               const deUint32  slicesLayers                    = 16u;
+               params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
+               params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.src.image.extent                   = defaultHalfExtent;
+               params2DTo3D.src.image.extent.depth             = slicesLayers;
+               params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
+               params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
+               params2DTo3D.dst.image.extent                   = defaultHalfExtent;
+               params2DTo3D.dst.image.extent.depth             = slicesLayers;
+               params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params2DTo3D.allocationKind                             = allocationKind;
+
+               const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
+               const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
+
+               for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+               {
+                       const VkImageSubresourceLayers  sourceLayer     =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationLayer        =
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                               0u,                                                     // uint32_t                             mipLevel;
+                               0u,                                                     // uint32_t                             baseArrayLayer;
+                               1u                                                      // uint32_t                             layerCount;
+                       };
+
+                       const VkImageCopy                               testCopy        =
+                       {
+                               sourceLayer,                                                                                                                            // VkImageSubresourceLayers     srcSubresource;
+                               {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                                         // VkOffset3D                           srcOffset;
+                               destinationLayer,                                                                                                                       // VkImageSubresourceLayers     dstSubresource;
+                               {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},       // VkOffset3D                           dstOffset;
+                               {
+                                       defaultHalfExtent.width - regionWidth*slicesLayersNdx,
+                                       defaultHalfExtent.height - regionHeight*slicesLayersNdx,
+                                       1
+                               }                                                                                                                                                       // VkExtent3D                           extent;
+                       };
+
+                       CopyRegion      imageCopy;
+                       imageCopy.imageCopy     = testCopy;
+
+                       params2DTo3D.regions.push_back(imageCopy);
+               }
+
+               group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
+       }
+}
+
+void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind);
+       addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind);
+       addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind);
+}
+
+void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx       = group->getTestContext();
+
+       {
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.buffer.size                          = defaultSize * defaultSize;
+               params.allocationKind                           = allocationKind;
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       0u,                                                                                     // VkDeviceSize                         bufferOffset;
+                       0u,                                                                                     // uint32_t                                     bufferRowLength;
+                       0u,                                                                                     // uint32_t                                     bufferImageHeight;
+                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
+                       {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
+                       defaultExtent                                                           // VkExtent3D                           imageExtent;
+               };
+               CopyRegion      copyRegion;
+               copyRegion.bufferImageCopy      = bufferImageCopy;
+
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
+       }
+
+       {
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.buffer.size                          = defaultSize * defaultSize;
+               params.allocationKind                           = allocationKind;
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
+                       0u,                                                                                     // uint32_t                                     bufferRowLength;
+                       0u,                                                                                     // uint32_t                                     bufferImageHeight;
+                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
+                       {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
+                       defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
+               };
+               CopyRegion      copyRegion;
+               copyRegion.bufferImageCopy      = bufferImageCopy;
+
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
+       }
+
+       {
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+               params.dst.buffer.size                          = defaultSize * defaultSize;
+               params.allocationKind                           = allocationKind;
+
+               const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
+               const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
+               const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
+               deUint32                        divisor         = 1;
+               for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
+               {
+                       const deUint32                  bufferRowLength         = defaultFourthSize;
+                       const deUint32                  bufferImageHeight       = defaultFourthSize;
+                       const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
+                       DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
+                       DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
+                       DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
+
+                       CopyRegion                              region;
+                       const VkBufferImageCopy bufferImageCopy         =
+                       {
+                               offset,                                         // VkDeviceSize                         bufferOffset;
+                               bufferRowLength,                        // uint32_t                                     bufferRowLength;
+                               bufferImageHeight,                      // uint32_t                                     bufferImageHeight;
+                               defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
+                               {0, 0, 0},                                      // VkOffset3D                           imageOffset;
+                               imageExtent                                     // VkExtent3D                           imageExtent;
+                       };
+                       region.bufferImageCopy  = bufferImageCopy;
+                       params.regions.push_back(region);
+               }
+
+               group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
+       }
+}
+
+void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx       = group->getTestContext();
+
+       {
+               TestParams      params;
+               params.src.buffer.size                          = defaultSize * defaultSize;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       0u,                                                                                     // VkDeviceSize                         bufferOffset;
+                       0u,                                                                                     // uint32_t                                     bufferRowLength;
+                       0u,                                                                                     // uint32_t                                     bufferImageHeight;
+                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
+                       {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
+                       defaultExtent                                                           // VkExtent3D                           imageExtent;
+               };
+               CopyRegion      copyRegion;
+               copyRegion.bufferImageCopy      = bufferImageCopy;
+
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
+       }
+
+       {
+               TestParams      params;
+               params.src.buffer.size                          = defaultSize * defaultSize;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
+
+               CopyRegion      region;
+               deUint32        divisor = 1;
+               for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
+               {
+                       const VkBufferImageCopy bufferImageCopy =
+                       {
+                               0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
+                               0u,                                                                                                                             // uint32_t                                     bufferRowLength;
+                               0u,                                                                                                                             // uint32_t                                     bufferImageHeight;
+                               defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
+                               {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
+                               {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
+                       };
+                       region.bufferImageCopy  = bufferImageCopy;
+                       params.regions.push_back(region);
+               }
+
+               group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
+       }
+
+       {
+               TestParams      params;
+               params.src.buffer.size                          = defaultSize * defaultSize;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind                           = allocationKind;
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
+                       defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferRowLength;
+                       defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferImageHeight;
+                       defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
+                       {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
+                       defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
+               };
+               CopyRegion      copyRegion;
+               copyRegion.bufferImageCopy      = bufferImageCopy;
+
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
+       }
+}
+
+void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&                               testCtx                                 = group->getTestContext();
+
+       {
+               TestParams                      params;
+               params.src.buffer.size  = defaultSize;
+               params.dst.buffer.size  = defaultSize;
+               params.allocationKind   = allocationKind;
+
+               const VkBufferCopy      bufferCopy      =
+               {
+                       0u,                             // VkDeviceSize srcOffset;
+                       0u,                             // VkDeviceSize dstOffset;
+                       defaultSize,    // VkDeviceSize size;
+               };
+
+               CopyRegion      copyRegion;
+               copyRegion.bufferCopy   = bufferCopy;
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
+       }
+
+       // Filter is VK_FILTER_NEAREST.
+       {
+               TestParams                      params;
+               params.src.buffer.size  = defaultFourthSize;
+               params.dst.buffer.size  = defaultFourthSize;
+               params.allocationKind   = allocationKind;
+
+               const VkBufferCopy      bufferCopy      =
+               {
+                       12u,    // VkDeviceSize srcOffset;
+                       4u,             // VkDeviceSize dstOffset;
+                       1u,             // VkDeviceSize size;
+               };
+
+               CopyRegion      copyRegion;
+               copyRegion.bufferCopy = bufferCopy;
+               params.regions.push_back(copyRegion);
+
+               group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
+       }
+
+       {
+               const deUint32          size            = 16;
+               TestParams                      params;
+               params.src.buffer.size  = size;
+               params.dst.buffer.size  = size * (size + 1);
+               params.allocationKind   = allocationKind;
+
+               // Copy region with size 1..size
+               for (unsigned int i = 1; i <= size; i++)
+               {
+                       const VkBufferCopy      bufferCopy      =
                        {
                                0,                      // VkDeviceSize srcOffset;
                                i * size,       // VkDeviceSize dstOffset;
@@ -3628,629 +4692,1589 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(copyRegion);
                }
 
-               bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
+               group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
+       }
+}
+
+void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               { 0, 0, 0 },
+                               { defaultSize, defaultSize, 1 }
+                       },                                      // VkOffset3D                           srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               { 0, 0, 0 },
+                               { defaultSize, defaultSize, 1 }
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
+
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
        }
 
-       // Blitting testcases.
+       // Filter is VK_FILTER_NEAREST.
        {
-               const std::string       description     ("Blit without scaling (whole)");
-               const std::string       testName        ("whole");
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.extent = defaultExtent;
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
 
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       const VkImageBlit                               imageBlit       =
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                        {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, defaultSize, 0},
+                               {0, 0, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       CopyRegion      region;
-                       region.imageBlit = imageBlit;
-                       params.regions.push_back(region);
-               }
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
+
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               // Filter is VK_FILTER_NEAREST.
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       params.filter                   = VK_FILTER_NEAREST;
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, 0, 0},
+                               {0, defaultSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
-               }
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
 
-               // Filter is VK_FILTER_LINEAR.
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       params.filter                   = VK_FILTER_LINEAR;
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, defaultSize, 0},
+                               {defaultSize, 0, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
-               }
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
        }
 
+       // Filter is VK_FILTER_LINEAR.
        {
-               const std::string       description     ("Blit with scaling (whole, src extent bigger)");
-               const std::string       testName        ("scaling_whole1");
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.extent = defaultHalfExtent;
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
 
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       // No mirroring.
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       const VkImageBlit                               imageBlit       =
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                        {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                                   srcOffsets[2];
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
-                               }                                       // VkOffset3D                                   dstOffset[2];
-                       };
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       CopyRegion      region;
-                       region.imageBlit        = imageBlit;
-                       params.regions.push_back(region);
-               }
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
+
+       // Flipping y coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {defaultHalfSize, 0, 0},
+                               {defaultSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {defaultSize, 0, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-               // Filter is VK_FILTER_NEAREST.
+       // Flipping x coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       params.filter                   = VK_FILTER_NEAREST;
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, defaultHalfSize, 0},
+                               {defaultHalfSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {0, defaultSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
-               }
+       // Flipping x and y coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, defaultSize, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
+
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
+
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               // Filter is VK_FILTER_LINEAR.
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultHalfExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       params.filter                   = VK_FILTER_LINEAR;
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                                   dstOffset[2];
+               };
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+               CopyRegion      region;
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
+       }
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
-               }
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
        }
 
+       // Filter is VK_FILTER_LINEAR.
        {
-               const std::string       description     ("Blit with scaling (whole, dst extent bigger)");
-               const std::string       testName        ("scaling_whole2");
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = defaultHalfExtent;
-               params.dst.image.extent = defaultExtent;
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" );
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultHalfExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       }                                       // VkOffset3D                                   dstOffset[2];
+               };
+
+               CopyRegion      region;
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
+       }
+
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageBlit                               imageBlit       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {defaultFourthSize, defaultFourthSize, 0},
+                               {defaultFourthSize*3, defaultFourthSize*3, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       }                                       // VkOffset3D                                   dstOffset[2];
+               };
+
+               CopyRegion      region;
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
+       }
 
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               CopyRegion      region;
+               for (int i = 0; i < defaultSize; i += defaultFourthSize)
                {
-                       const VkImageBlit                               imageBlit       =
+                       const VkImageBlit                       imageBlit       =
                        {
                                defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                                {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
+                                       {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
+                                       {defaultSize - i, defaultSize - i, 1}
                                },                                      // VkOffset3D                                   srcOffsets[2];
 
                                defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
                                {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
+                                       {i, i, 0},
+                                       {i + defaultFourthSize, i + defaultFourthSize, 1}
                                }                                       // VkOffset3D                                   dstOffset[2];
                        };
-
-                       CopyRegion      region;
                        region.imageBlit        = imageBlit;
                        params.regions.push_back(region);
                }
+       }
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
+
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
+
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
+
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
+
+               params.dst.image.format = VK_FORMAT_R32_SFLOAT;
+               const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+
+               params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
+               const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
+
+void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind);
+       addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind);
+       addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind);
+       addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind);
+       addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind);
+       addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind);
+       addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind);
+       addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind);
+       addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind);
+}
+
+struct BlitColorTestParams
+{
+       TestParams              params;
+       const VkFormat* compatibleFormats;
+       bool                    onlyNearest;
+};
+
+bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
+{
+       bool result = true;
+
+       if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
+
+               result =
+                       de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
+                       de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
+       }
+
+       return result;
+}
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
+{
+       tcu::TestContext& testCtx                               = group->getTestContext();
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
-               }
+       const VkImageLayout blitSrcLayouts[]    =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout blitDstLayouts[]    =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
 
-               // Filter is VK_FILTER_LINEAR.
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
+       {
+               testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
                {
-                       params.filter                   = VK_FILTER_LINEAR;
-
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+                       testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+                       testParams.params.filter                        = VK_FILTER_NEAREST;
+                       const std::string testName                      = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
+                                                                                                 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
+                       const std::string description           = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
+                                                                                                 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
+                       group->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, testParams.params));
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+                       if (!testParams.onlyNearest)
+                       {
+                               testParams.params.filter                = VK_FILTER_LINEAR;
+                               group->addChild(new BlittingTestCase(testCtx, testName + "_linear", description, testParams.params));
+                       }
                }
        }
+}
 
+void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
+{
+       for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
        {
-               const std::string       description     ("Blit with scaling and offset (whole, dst extent bigger)");
-               const std::string       testName        ("scaling_and_offset");
+               testParams.params.dst.image.format      = testParams.compatibleFormats[dstFormatIndex];
+               if (!isSupportedByFramework(testParams.params.dst.image.format))
+                       continue;
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.extent = defaultExtent;
-
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {defaultFourthSize, defaultFourthSize, 0},
-                                       {defaultFourthSize*3, defaultFourthSize*3, 1}
-                               },                                      // VkOffset3D                                   srcOffsets[2];
+               if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
+                       continue;
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               }                                       // VkOffset3D                                   dstOffset[2];
-                       };
+               const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
+               addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
+       }
+}
 
-                       CopyRegion      region;
-                       region.imageBlit        = imageBlit;
-                       params.regions.push_back(region);
-               }
+const VkFormat compatibleFormatsUInts[]        =
+{
+       VK_FORMAT_R8_UINT,
+       VK_FORMAT_R8G8_UINT,
+       VK_FORMAT_R8G8B8_UINT,
+       VK_FORMAT_B8G8R8_UINT,
+       VK_FORMAT_R8G8B8A8_UINT,
+       VK_FORMAT_B8G8R8A8_UINT,
+       VK_FORMAT_A8B8G8R8_UINT_PACK32,
+       VK_FORMAT_A2R10G10B10_UINT_PACK32,
+       VK_FORMAT_A2B10G10R10_UINT_PACK32,
+       VK_FORMAT_R16_UINT,
+       VK_FORMAT_R16G16_UINT,
+       VK_FORMAT_R16G16B16_UINT,
+       VK_FORMAT_R16G16B16A16_UINT,
+       VK_FORMAT_R32_UINT,
+       VK_FORMAT_R32G32_UINT,
+       VK_FORMAT_R32G32B32_UINT,
+       VK_FORMAT_R32G32B32A32_UINT,
+       VK_FORMAT_R64_UINT,
+       VK_FORMAT_R64G64_UINT,
+       VK_FORMAT_R64G64B64_UINT,
+       VK_FORMAT_R64G64B64A64_UINT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormatsSInts[]        =
+{
+       VK_FORMAT_R8_SINT,
+       VK_FORMAT_R8G8_SINT,
+       VK_FORMAT_R8G8B8_SINT,
+       VK_FORMAT_B8G8R8_SINT,
+       VK_FORMAT_R8G8B8A8_SINT,
+       VK_FORMAT_B8G8R8A8_SINT,
+       VK_FORMAT_A8B8G8R8_SINT_PACK32,
+       VK_FORMAT_A2R10G10B10_SINT_PACK32,
+       VK_FORMAT_A2B10G10R10_SINT_PACK32,
+       VK_FORMAT_R16_SINT,
+       VK_FORMAT_R16G16_SINT,
+       VK_FORMAT_R16G16B16_SINT,
+       VK_FORMAT_R16G16B16A16_SINT,
+       VK_FORMAT_R32_SINT,
+       VK_FORMAT_R32G32_SINT,
+       VK_FORMAT_R32G32B32_SINT,
+       VK_FORMAT_R32G32B32A32_SINT,
+       VK_FORMAT_R64_SINT,
+       VK_FORMAT_R64G64_SINT,
+       VK_FORMAT_R64G64B64_SINT,
+       VK_FORMAT_R64G64B64A64_SINT,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormatsFloats[]       =
+{
+       VK_FORMAT_R4G4_UNORM_PACK8,
+       VK_FORMAT_R4G4B4A4_UNORM_PACK16,
+       VK_FORMAT_B4G4R4A4_UNORM_PACK16,
+       VK_FORMAT_R5G6B5_UNORM_PACK16,
+       VK_FORMAT_B5G6R5_UNORM_PACK16,
+       VK_FORMAT_R5G5B5A1_UNORM_PACK16,
+       VK_FORMAT_B5G5R5A1_UNORM_PACK16,
+       VK_FORMAT_A1R5G5B5_UNORM_PACK16,
+       VK_FORMAT_R8_UNORM,
+       VK_FORMAT_R8_SNORM,
+       VK_FORMAT_R8_USCALED,
+       VK_FORMAT_R8_SSCALED,
+       VK_FORMAT_R8G8_UNORM,
+       VK_FORMAT_R8G8_SNORM,
+       VK_FORMAT_R8G8_USCALED,
+       VK_FORMAT_R8G8_SSCALED,
+       VK_FORMAT_R8G8B8_UNORM,
+       VK_FORMAT_R8G8B8_SNORM,
+       VK_FORMAT_R8G8B8_USCALED,
+       VK_FORMAT_R8G8B8_SSCALED,
+       VK_FORMAT_B8G8R8_UNORM,
+       VK_FORMAT_B8G8R8_SNORM,
+       VK_FORMAT_B8G8R8_USCALED,
+       VK_FORMAT_B8G8R8_SSCALED,
+       VK_FORMAT_R8G8B8A8_UNORM,
+       VK_FORMAT_R8G8B8A8_SNORM,
+       VK_FORMAT_R8G8B8A8_USCALED,
+       VK_FORMAT_R8G8B8A8_SSCALED,
+       VK_FORMAT_B8G8R8A8_UNORM,
+       VK_FORMAT_B8G8R8A8_SNORM,
+       VK_FORMAT_B8G8R8A8_USCALED,
+       VK_FORMAT_B8G8R8A8_SSCALED,
+       VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+       VK_FORMAT_A8B8G8R8_SNORM_PACK32,
+       VK_FORMAT_A8B8G8R8_USCALED_PACK32,
+       VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
+       VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+       VK_FORMAT_A2R10G10B10_SNORM_PACK32,
+       VK_FORMAT_A2R10G10B10_USCALED_PACK32,
+       VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
+       VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+       VK_FORMAT_A2B10G10R10_SNORM_PACK32,
+       VK_FORMAT_A2B10G10R10_USCALED_PACK32,
+       VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
+       VK_FORMAT_R16_UNORM,
+       VK_FORMAT_R16_SNORM,
+       VK_FORMAT_R16_USCALED,
+       VK_FORMAT_R16_SSCALED,
+       VK_FORMAT_R16_SFLOAT,
+       VK_FORMAT_R16G16_UNORM,
+       VK_FORMAT_R16G16_SNORM,
+       VK_FORMAT_R16G16_USCALED,
+       VK_FORMAT_R16G16_SSCALED,
+       VK_FORMAT_R16G16_SFLOAT,
+       VK_FORMAT_R16G16B16_UNORM,
+       VK_FORMAT_R16G16B16_SNORM,
+       VK_FORMAT_R16G16B16_USCALED,
+       VK_FORMAT_R16G16B16_SSCALED,
+       VK_FORMAT_R16G16B16_SFLOAT,
+       VK_FORMAT_R16G16B16A16_UNORM,
+       VK_FORMAT_R16G16B16A16_SNORM,
+       VK_FORMAT_R16G16B16A16_USCALED,
+       VK_FORMAT_R16G16B16A16_SSCALED,
+       VK_FORMAT_R16G16B16A16_SFLOAT,
+       VK_FORMAT_R32_SFLOAT,
+       VK_FORMAT_R32G32_SFLOAT,
+       VK_FORMAT_R32G32B32_SFLOAT,
+       VK_FORMAT_R32G32B32A32_SFLOAT,
+       VK_FORMAT_R64_SFLOAT,
+       VK_FORMAT_R64G64_SFLOAT,
+       VK_FORMAT_R64G64B64_SFLOAT,
+       VK_FORMAT_R64G64B64A64_SFLOAT,
+//     VK_FORMAT_B10G11R11_UFLOAT_PACK32,
+//     VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
+//     VK_FORMAT_BC1_RGB_UNORM_BLOCK,
+//     VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
+//     VK_FORMAT_BC2_UNORM_BLOCK,
+//     VK_FORMAT_BC3_UNORM_BLOCK,
+//     VK_FORMAT_BC4_UNORM_BLOCK,
+//     VK_FORMAT_BC4_SNORM_BLOCK,
+//     VK_FORMAT_BC5_UNORM_BLOCK,
+//     VK_FORMAT_BC5_SNORM_BLOCK,
+//     VK_FORMAT_BC6H_UFLOAT_BLOCK,
+//     VK_FORMAT_BC6H_SFLOAT_BLOCK,
+//     VK_FORMAT_BC7_UNORM_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
+//     VK_FORMAT_EAC_R11_UNORM_BLOCK,
+//     VK_FORMAT_EAC_R11_SNORM_BLOCK,
+//     VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
+//     VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
+//     VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
+//     VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormatsSrgb[]         =
+{
+       VK_FORMAT_R8_SRGB,
+       VK_FORMAT_R8G8_SRGB,
+       VK_FORMAT_R8G8B8_SRGB,
+       VK_FORMAT_B8G8R8_SRGB,
+       VK_FORMAT_R8G8B8A8_SRGB,
+       VK_FORMAT_B8G8R8A8_SRGB,
+       VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+//     VK_FORMAT_BC1_RGB_SRGB_BLOCK,
+//     VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
+//     VK_FORMAT_BC2_SRGB_BLOCK,
+//     VK_FORMAT_BC3_SRGB_BLOCK,
+//     VK_FORMAT_BC7_SRGB_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
+//     VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
+//     VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
+
+       VK_FORMAT_UNDEFINED
+};
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+const VkFormat dedicatedAllocationBlittingFormatsToTest[]      =
+{
+       // compatibleFormatsUInts
+       VK_FORMAT_R8_UINT,
+       VK_FORMAT_R64G64B64A64_UINT,
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+       // compatibleFormatsSInts
+       VK_FORMAT_R8_SINT,
+       VK_FORMAT_R64G64B64A64_SINT,
 
+       // compatibleFormatsFloats
+       VK_FORMAT_R4G4_UNORM_PACK8,
+       VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+       // compatibleFormatsSrgb
+       VK_FORMAT_R8_SRGB,
+       VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+};
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
-               }
+void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       const struct {
+               const VkFormat* compatibleFormats;
+               const bool              onlyNearest;
+       }       colorImageFormatsToTestBlit[]                   =
+       {
+               { compatibleFormatsUInts,       true    },
+               { compatibleFormatsSInts,       true    },
+               { compatibleFormatsFloats,      false   },
+               { compatibleFormatsSrgb,        false   },
+       };
 
-               // Filter is VK_FILTER_LINEAR.
-               {
-                       params.filter                   = VK_FILTER_LINEAR;
+       const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+       TestParams      params;
+       params.src.image.imageType      = VK_IMAGE_TYPE_2D;
+       params.src.image.extent         = defaultExtent;
+       params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
+       params.dst.image.extent         = defaultExtent;
+       params.allocationKind           = allocationKind;
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
+       CopyRegion      region;
+       for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
+       {
+               const VkImageBlit                       imageBlit       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
-               }
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {i, 0, 0},
+                               {i + defaultFourthSize / j, defaultFourthSize / j, 1}
+                       }                                       // VkOffset3D                                   dstOffset[2];
+               };
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
        }
-
+       for (int i = 0; i < defaultSize; i += defaultFourthSize)
        {
-               const std::string       description     ("Blit without scaling (partial)");
-               const std::string       testName        ("without_scaling_partial");
-
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = defaultExtent;
-               params.dst.image.extent = defaultExtent;
-
+               const VkImageBlit                       imageBlit       =
                {
-                       CopyRegion      region;
-                       for (int i = 0; i < defaultSize; i += defaultFourthSize)
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                        {
-                               const VkImageBlit                       imageBlit       =
-                               {
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                                       {
-                                               {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
-                                               {defaultSize - i, defaultSize - i, 1}
-                                       },                                      // VkOffset3D                                   srcOffsets[2];
+                               {i, i, 0},
+                               {i + defaultFourthSize, i + defaultFourthSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
 
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                                       {
-                                               {i, i, 0},
-                                               {i + defaultFourthSize, i + defaultFourthSize, 1}
-                                       }                                       // VkOffset3D                                   dstOffset[2];
-                               };
-                               region.imageBlit        = imageBlit;
-                               params.regions.push_back(region);
-                       }
-               }
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {i, defaultSize / 2, 0},
+                               {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
+                       }                                       // VkOffset3D                                   dstOffset[2];
+               };
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
+       }
+
+       if (allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
+               for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
+                       dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
+       }
 
-               // Filter is VK_FILTER_NEAREST.
+       for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
+       {
+               const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
+               const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
+               for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
                {
-                       params.filter                   = VK_FILTER_NEAREST;
+                       params.src.image.format = compatibleFormats[srcFormatIndex];
+                       if (!isSupportedByFramework(params.src.image.format))
+                               continue;
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+                       BlitColorTestParams             testParams;
+                       testParams.params                               = params;
+                       testParams.compatibleFormats    = compatibleFormats;
+                       testParams.onlyNearest                  = onlyNearest;
 
+                       const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
+                       addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
+               }
+       }
+}
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
+void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
+{
+       const VkImageLayout blitSrcLayouts[]    =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout blitDstLayouts[]    =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
 
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
-               }
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
+       {
+               params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
 
-               // Filter is VK_FILTER_LINEAR.
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
                {
-                       params.filter                   = VK_FILTER_LINEAR;
+                       params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
+                       params.filter                                           = VK_FILTER_NEAREST;
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+                       const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
+                                                                                         getImageLayoutCaseName(params.dst.image.operationLayout);
+                       const std::string description   = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
+                                                                                         " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
 
-                       params.dst.image.format = VK_FORMAT_R32_SFLOAT;
-                       const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
-
-                       params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
-                       const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+                       group->addChild(new BlittingTestCase(group->getTestContext(), testName + "_nearest", description, params));
                }
        }
+}
+
+void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       const VkFormat  depthAndStencilFormats[]        =
+       {
+               VK_FORMAT_D16_UNORM,
+               VK_FORMAT_X8_D24_UNORM_PACK32,
+               VK_FORMAT_D32_SFLOAT,
+               VK_FORMAT_S8_UINT,
+               VK_FORMAT_D16_UNORM_S8_UINT,
+               VK_FORMAT_D24_UNORM_S8_UINT,
+               VK_FORMAT_D32_SFLOAT_S8_UINT,
+       };
+
+       const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
+       const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
 
+       for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
        {
-               const std::string       description     ("Blit with scaling (partial)");
-               const std::string       testName        ("scaling_partial");
+               TestParams      params;
+               params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.src.image.extent                         = defaultExtent;
+               params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
+               params.dst.image.extent                         = defaultExtent;
+               params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+               params.dst.image.format                         = params.src.image.format;
+               params.allocationKind                           = allocationKind;
 
-               // Test Color formats.
+               CopyRegion      region;
+               for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
                {
-                       TestParams      params;
-                       params.src.image.extent = defaultExtent;
-                       params.dst.image.extent = defaultExtent;
+                       const VkOffset3D        srcOffset0      = {0, 0, 0};
+                       const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
+                       const VkOffset3D        dstOffset0      = {i, 0, 0};
+                       const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
 
-                       CopyRegion      region;
-                       for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
+                       if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
                        {
                                const VkImageBlit                       imageBlit       =
                                {
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                                       {
-                                               {0, 0, 0},
-                                               {defaultSize, defaultSize, 1}
-                                       },                                      // VkOffset3D                                   srcOffsets[2];
-
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                                       {
-                                               {i, 0, 0},
-                                               {i + defaultFourthSize / j, defaultFourthSize / j, 1}
-                                       }                                       // VkOffset3D                                   dstOffset[2];
+                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
+                                       { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
+                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
+                                       { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
                                };
                                region.imageBlit        = imageBlit;
                                params.regions.push_back(region);
                        }
-                       for (int i = 0; i < defaultSize; i += defaultFourthSize)
+                       if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
                        {
                                const VkImageBlit                       imageBlit       =
                                {
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                                       {
-                                               {i, i, 0},
-                                               {i + defaultFourthSize, i + defaultFourthSize, 1}
-                                       },                                      // VkOffset3D                                   srcOffsets[2];
-
-                                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                                       {
-                                               {i, defaultSize / 2, 0},
-                                               {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
-                                       }                                       // VkOffset3D                                   dstOffset[2];
+                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
+                                       { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
+                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
+                                       { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
                                };
                                region.imageBlit        = imageBlit;
                                params.regions.push_back(region);
                        }
-
-                       addBlittingTestsAllFormats(blitImgAllFormatsTests.get(), testCtx, params);
                }
-
-               // Test Depth and Stencil formats.
+               for (int i = 0; i < defaultSize; i += defaultFourthSize)
                {
-                       const VkFormat  compatibleDepthAndStencilFormats[]      =
-                       {
-                               VK_FORMAT_D16_UNORM,
-                               VK_FORMAT_X8_D24_UNORM_PACK32,
-                               VK_FORMAT_D32_SFLOAT,
-                               VK_FORMAT_S8_UINT,
-                               VK_FORMAT_D16_UNORM_S8_UINT,
-                               VK_FORMAT_D24_UNORM_S8_UINT,
-                               VK_FORMAT_D32_SFLOAT_S8_UINT,
-                       };
+                       const VkOffset3D        srcOffset0      = {i, i, 0};
+                       const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
+                       const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
+                       const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
 
-                       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(compatibleDepthAndStencilFormats); ++compatibleFormatsIndex)
+                       if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
                        {
-                               TestParams params;
-
-                               params.src.image.extent = defaultExtent;
-                               params.dst.image.extent = defaultExtent;
-                               params.src.image.format = compatibleDepthAndStencilFormats[compatibleFormatsIndex];
-                               params.dst.image.format = params.src.image.format;
-                               std::ostringstream      oss;
-                               oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
-
-                               const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
-                               const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
-
-                               CopyRegion      region;
-                               for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
+                               const VkImageBlit                       imageBlit       =
                                {
-                                       const VkOffset3D        srcOffset0      = {0, 0, 0};
-                                       const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
-                                       const VkOffset3D        dstOffset0      = {i, 0, 0};
-                                       const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
-
-                                       if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
-                                       {
-                                               const VkImageBlit                       imageBlit       =
-                                               {
-                                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
-                                                       { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
-                                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
-                                                       { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
-                                               };
-                                               region.imageBlit        = imageBlit;
-                                               params.regions.push_back(region);
-                                       }
-                                       if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
-                                       {
-                                               const VkImageBlit                       imageBlit       =
-                                               {
-                                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
-                                                       { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
-                                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
-                                                       { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
-                                               };
-                                               region.imageBlit        = imageBlit;
-                                               params.regions.push_back(region);
-                                       }
-                               }
-                               for (int i = 0; i < defaultSize; i += defaultFourthSize)
+                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
+                                       { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
+                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
+                                       { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
+                               };
+                               region.imageBlit        = imageBlit;
+                               params.regions.push_back(region);
+                       }
+                       if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
+                       {
+                               const VkImageBlit                       imageBlit       =
                                {
-                                       const VkOffset3D        srcOffset0      = {i, i, 0};
-                                       const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
-                                       const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
-                                       const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
-
-                                       if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
-                                       {
-                                               const VkImageBlit                       imageBlit       =
-                                               {
-                                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
-                                                       { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
-                                                       defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
-                                                       { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
-                                               };
-                                               region.imageBlit        = imageBlit;
-                                               params.regions.push_back(region);
-                                       }
-                                       if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
-                                       {
-                                               const VkImageBlit                       imageBlit       =
-                                               {
-                                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
-                                                       { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
-                                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
-                                                       { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
-                                               };
-                                               region.imageBlit        = imageBlit;
-                                               params.regions.push_back(region);
-                                       }
-                               }
-
-                               params.filter                   = VK_FILTER_NEAREST;
-                               blitImgAllFormatsTests->addChild(new BlittingTestCase(testCtx, oss.str() + "_nearest", description, params));
+                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
+                                       { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
+                                       defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
+                                       { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
+                               };
+                               region.imageBlit        = imageBlit;
+                               params.regions.push_back(region);
                        }
                }
-       }
-       blittingImageTests->addChild(blitImgSimpleTests.release());
-       blittingImageTests->addChild(blitImgAllFormatsTests.release());
 
+               const std::string testName              = getFormatCaseName(params.src.image.format) + "_" +
+                                                                                 getFormatCaseName(params.dst.image.format);
+               const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
+                                                                                 " to " + getFormatCaseName(params.dst.image.format);
+               addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
+       }
+}
 
-       // Resolve image to image testcases.
-       const VkSampleCountFlagBits     samples[]               =
-       {
-               VK_SAMPLE_COUNT_2_BIT,
-               VK_SAMPLE_COUNT_4_BIT,
-               VK_SAMPLE_COUNT_8_BIT,
-               VK_SAMPLE_COUNT_16_BIT,
-               VK_SAMPLE_COUNT_32_BIT,
-               VK_SAMPLE_COUNT_64_BIT
-       };
-       const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
+void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind);
+       addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind);
+}
 
-       {
-               const std::string       description     ("Resolve from image to image");
-               const std::string       testName        ("whole");
+void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind);
+       addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind);
+}
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = resolveExtent;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.dst.image.extent = resolveExtent;
+const VkSampleCountFlagBits    samples[]               =
+{
+       VK_SAMPLE_COUNT_2_BIT,
+       VK_SAMPLE_COUNT_4_BIT,
+       VK_SAMPLE_COUNT_8_BIT,
+       VK_SAMPLE_COUNT_16_BIT,
+       VK_SAMPLE_COUNT_32_BIT,
+       VK_SAMPLE_COUNT_64_BIT
+};
+const VkExtent3D                       resolveExtent   = {256u, 256u, 1};
 
+void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = resolveExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.extent                         = resolveExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
                {
-                       const VkImageSubresourceLayers  sourceLayer     =
-                       {
-                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
-                               0u,                                                     // uint32_t                             mipLevel;
-                               0u,                                                     // uint32_t                             baseArrayLayer;
-                               1u                                                      // uint32_t                             layerCount;
-                       };
-                       const VkImageResolve                    testResolve     =
-                       {
-                               sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
-                               {0, 0, 0},              // VkOffset3D                           srcOffset;
-                               sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
-                               {0, 0, 0},              // VkOffset3D                           dstOffset;
-                               resolveExtent,  // VkExtent3D                           extent;
-                       };
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // uint32_t                             baseArrayLayer;
+                       1u                                                      // uint32_t                             layerCount;
+               };
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},              // VkOffset3D                           srcOffset;
+                       sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
+                       {0, 0, 0},              // VkOffset3D                           dstOffset;
+                       resolveExtent,  // VkExtent3D                           extent;
+               };
 
-                       CopyRegion      imageResolve;
-                       imageResolve.imageResolve       = testResolve;
-                       params.regions.push_back(imageResolve);
-               }
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve       = testResolve;
+               params.regions.push_back(imageResolve);
+       }
 
-               for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+       for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+       {
+               params.samples                                  = samples[samplesIndex];
+               const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
+               group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
+       }
+}
+
+void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = resolveExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.extent                         = resolveExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
                {
-                       params.samples = samples[samplesIndex];
-                       std::ostringstream caseName;
-                       caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
-                       resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
-               }
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // uint32_t                             baseArrayLayer;
+                       1u                                                      // uint32_t                             layerCount;
+               };
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},              // VkOffset3D                           srcOffset;
+                       sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
+                       {64u, 64u, 0},          // VkOffset3D                           dstOffset;
+                       {128u, 128u, 1u},       // VkExtent3D                           extent;
+               };
+
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve = testResolve;
+               params.regions.push_back(imageResolve);
        }
 
+       for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
        {
-               const std::string       description     ("Resolve from image to image");
-               const std::string       testName        ("partial");
+               params.samples                                  = samples[samplesIndex];
+               const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
+               group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
+       }
+}
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = resolveExtent;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.dst.image.extent = resolveExtent;
+void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = resolveExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.extent                         = resolveExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // uint32_t                             baseArrayLayer;
+                       1u                                                      // uint32_t                             layerCount;
+               };
 
+               for (int i = 0; i < 256; i += 64)
                {
-                       const VkImageSubresourceLayers  sourceLayer     =
-                       {
-                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
-                               0u,                                                     // uint32_t                             mipLevel;
-                               0u,                                                     // uint32_t                             baseArrayLayer;
-                               1u                                                      // uint32_t                             layerCount;
-                       };
                        const VkImageResolve                    testResolve     =
                        {
                                sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
-                               {0, 0, 0},              // VkOffset3D                           srcOffset;
+                               {i, i, 0},              // VkOffset3D                           srcOffset;
                                sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
-                               {64u, 64u, 0},          // VkOffset3D                           dstOffset;
-                               {128u, 128u, 1u},       // VkExtent3D                           extent;
+                               {i, 0, 0},              // VkOffset3D                           dstOffset;
+                               {64u, 64u, 1u}, // VkExtent3D                           extent;
                        };
 
                        CopyRegion      imageResolve;
                        imageResolve.imageResolve = testResolve;
                        params.regions.push_back(imageResolve);
                }
+       }
 
-               for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+       for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+       {
+               params.samples                                  = samples[samplesIndex];
+               const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
+               group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
+       }
+}
+
+void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
                {
-                       params.samples = samples[samplesIndex];
-                       std::ostringstream caseName;
-                       caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
-                       resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
-               }
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // uint32_t                             baseArrayLayer;
+                       1u                                                      // uint32_t                             layerCount;
+               };
+
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},                      // VkOffset3D                           srcOffset;
+                       sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
+                       {0, 0, 0},                      // VkOffset3D                           dstOffset;
+                       defaultExtent,          // VkExtent3D                           extent;
+               };
+
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve       = testResolve;
+               params.regions.push_back(imageResolve);
        }
 
+       for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
        {
-               const std::string       description     ("Resolve from image to image");
-               const std::string       testName        ("with_regions");
+               params.samples                                  = samples[samplesIndex];
+               const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
+               group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
+       }
+}
 
-               TestParams                      params;
-               params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent = resolveExtent;
-               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-               params.dst.image.extent = resolveExtent;
+void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       TestParams      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.extent                         = defaultExtent;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.extent                         = defaultExtent;
+       params.dst.image.extent.depth           = 5u;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // uint32_t                             mipLevel;
+                       layerNdx,                                               // uint32_t                             baseArrayLayer;
+                       1u                                                              // uint32_t                             layerCount;
+               };
 
+               const VkImageResolve                    testResolve     =
                {
-                       const VkImageSubresourceLayers  sourceLayer     =
-                       {
-                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
-                               0u,                                                     // uint32_t                             mipLevel;
-                               0u,                                                     // uint32_t                             baseArrayLayer;
-                               1u                                                      // uint32_t                             layerCount;
-                       };
+                       sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},                      // VkOffset3D                           srcOffset;
+                       sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
+                       {0, 0, 0},                      // VkOffset3D                           dstOffset;
+                       defaultExtent,          // VkExtent3D                           extent;
+               };
 
-                       for (int i = 0; i < 256; i += 64)
-                       {
-                               const VkImageResolve                    testResolve     =
-                               {
-                                       sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
-                                       {i, i, 0},              // VkOffset3D                           srcOffset;
-                                       sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
-                                       {i, 0, 0},              // VkOffset3D                           dstOffset;
-                                       {64u, 64u, 1u}, // VkExtent3D                           extent;
-                               };
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve       = testResolve;
+               params.regions.push_back(imageResolve);
+       }
 
-                               CopyRegion      imageResolve;
-                               imageResolve.imageResolve = testResolve;
-                               params.regions.push_back(imageResolve);
-                       }
-               }
+       for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+       {
+               params.samples                                  = samples[samplesIndex];
+               const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
+               group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
+       }
+}
+
+void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext&       testCtx                 = group->getTestContext();
+       TestParams                      params;
+       params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
+       params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // uint32_t                             baseArrayLayer;
+                       1u                                                      // uint32_t                             layerCount;
+               };
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},              // VkOffset3D                           srcOffset;
+                       sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
+                       {0, 0, 0},              // VkOffset3D                           dstOffset;
+                       resolveExtent,  // VkExtent3D                           extent;
+               };
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve       = testResolve;
+               params.regions.push_back(imageResolve);
+       }
+
+       const VkExtent3D imageExtents[]         =
+       {
+               { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
+               { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
+               { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
+       };
 
+       for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
+       {
+               const VkExtent3D&       srcImageSize    = imageExtents[srcImageExtentIndex];
+               params.src.image.extent                         = srcImageSize;
+               params.dst.image.extent                         = resolveExtent;
+               for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+               {
+                       params.samples  = samples[samplesIndex];
+                       std::ostringstream testName;
+                       testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
+                       std::ostringstream description;
+                       description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
+                                               << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
+                       group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
+               }
+       }
+       for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
+       {
+               const VkExtent3D&       dstImageSize    = imageExtents[dstImageExtentIndex];
+               params.src.image.extent                         = resolveExtent;
+               params.dst.image.extent                         = dstImageSize;
                for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
                {
-                       params.samples = samples[samplesIndex];
-                       std::ostringstream caseName;
-                       caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
-                       resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
+                       params.samples  = samples[samplesIndex];
+                       std::ostringstream testName;
+                       testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
+                       std::ostringstream description;
+                       description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
+                                               << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
+                       group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
                }
        }
+}
+
+void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind);
+       addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind);
+       addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind);
+       addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind);
+       addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind);
+       addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind);
+}
+
+void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
+       addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
+       addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
+       addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
+       addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
+       addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
+}
+
+void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group)
+{
+       addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED);
+}
+
+void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
+{
+       addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
 
-       copiesAndBlittingTests->addChild(imageToImageTests.release());
-       copiesAndBlittingTests->addChild(imageToBufferTests.release());
-       copiesAndBlittingTests->addChild(bufferToImageTests.release());
-       copiesAndBlittingTests->addChild(bufferToBufferTests.release());
-       copiesAndBlittingTests->addChild(blittingImageTests.release());
-       copiesAndBlittingTests->addChild(resolveImageTests.release());
+       copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core",                                       "Core Copies And Blitting Tests",                                                               addCoreCopiesAndBlittingTests));
+       copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",       "Copies And Blitting Tests For Dedicated Memory Allocation",    addDedicatedAllocationCopiesAndBlittingTests));
 
        return copiesAndBlittingTests.release();
 }