Fix layout transition in blitting tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
index 98a8285..c08e6bd 100644 (file)
 
 #include "deStringUtil.hpp"
 #include "deUniquePtr.hpp"
-#include "deMath.h"
 
 #include "tcuImageCompare.hpp"
 #include "tcuTexture.hpp"
 #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
 {
 
@@ -61,12 +65,28 @@ enum MirrorMode
        MIRROR_MODE_LAST
 };
 
-}
-
-using namespace vk;
+enum AllocationKind
+{
+       ALLOCATION_KIND_SUBALLOCATED,
+       ALLOCATION_KIND_DEDICATED,
+};
 
-namespace
+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)
 {
@@ -104,13 +124,14 @@ struct ImageParms
        VkImageType             imageType;
        VkFormat                format;
        VkExtent3D              extent;
+       VkImageLayout   operationLayout;
 };
 
 struct TestParams
 {
-       union
+       union Data
        {
-               struct
+               struct Buffer
                {
                        VkDeviceSize    size;
                } buffer;
@@ -125,8 +146,71 @@ struct TestParams
                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;
@@ -228,94 +312,97 @@ 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_RESET_COMMAND_BUFFER_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))
                                {
-                                       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))
-                                               {
-                                                       buffer.setPixDepth(redColor[x % 4], x, y, z);
-                                                       if (tcu::hasStencilComponent(buffer.getFormat().order))
-                                                               buffer.setPixStencil(255 * (int)redColor[y % 4], x, y, z);
-                                               }
-                                               else
-                                                       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(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))
+                               {
+                                       buffer.setPixDepth(redColor[x % 4], x, y, z);
+                                       if (tcu::hasStencilComponent(buffer.getFormat().order))
+                                               buffer.setPixStencil(255 * (int)redColor[y % 4], x, y, z);
+                               }
+                               else
+                                       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;
                }
        }
 }
@@ -333,12 +420,13 @@ void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bu
 
 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;
@@ -360,7 +448,7 @@ 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()));
        }
 
@@ -378,7 +466,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;
@@ -391,7 +481,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
                image,                                                                                  // VkImage                                      image;
                {                                                                                               // VkImageSubresourceRange      subresourceRange;
-                       aspect,                 // VkImageAspectFlags   aspect;
+                       formatAspect,   // VkImageAspectFlags   aspect;
                        0u,                             // deUint32                             baseMipLevel;
                        1u,                             // deUint32                             mipLevels;
                        0u,                             // deUint32                             baseArraySlice;
@@ -411,7 +501,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
                VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
                image,                                                                                  // VkImage                                      image;
                {                                                                                               // VkImageSubresourceRange      subresourceRange;
-                       aspect,                                         // VkImageAspectFlags   aspect;
+                       formatAspect,                           // VkImageAspectFlags   aspect;
                        0u,                                                     // deUint32                             baseMipLevel;
                        1u,                                                     // deUint32                             mipLevels;
                        0u,                                                     // deUint32                             baseArraySlice;
@@ -448,7 +538,8 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff
        };
 
        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, 1, &preImageBarrier);
+       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));
@@ -485,13 +576,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");
        }
 
@@ -526,7 +617,9 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                    image,
                                                                                                         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();
@@ -552,7 +645,7 @@ 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()));
 
                deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
@@ -560,20 +653,20 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                  image,
        }
 
        // 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;
+                       formatAspect,                   // VkImageAspectFlags   aspectMask;
                        0u,                                             // deUint32                             baseMipLevel;
                        1u,                                             // deUint32                             mipLevels;
                        0u,                                             // deUint32                             baseArraySlice;
@@ -601,12 +694,12 @@ 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;
@@ -615,6 +708,7 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                    image,
        };
 
        // Copy image to buffer
+       const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
        const VkBufferImageCopy         copyRegion              =
        {
                0u,                                                                     // VkDeviceSize                         bufferOffset;
@@ -723,22 +817,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,
@@ -754,11 +857,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 |
@@ -770,7 +873,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()));
        }
 
@@ -781,11 +884,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 |
@@ -797,7 +900,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()));
        }
 }
@@ -807,14 +910,14 @@ 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));
+                                                                                                                                                               (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();
 
@@ -838,7 +941,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;
@@ -847,7 +950,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
@@ -857,7 +960,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;
@@ -866,7 +969,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;
                        }
                },
        };
@@ -881,7 +984,7 @@ 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));
 
        submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
@@ -906,12 +1009,12 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r
 
                        if (isFloatFormat(result.getFormat()))
                        {
-                               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
+                               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 comparsion", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
+                               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
                                        return tcu::TestStatus::fail("CopiesAndBlitting test");
                        }
                }
@@ -924,12 +1027,12 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r
 
                        if (isFloatFormat(result.getFormat()))
                        {
-                               if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
+                               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 comparsion", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
+                               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
                                        return tcu::TestStatus::fail("CopiesAndBlitting test");
                        }
                }
@@ -938,12 +1041,37 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r
        {
                if (isFloatFormat(result.getFormat()))
                {
-                       if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
+                       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 comparsion", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
+                       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");
                }
        }
@@ -953,9 +1081,18 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r
 
 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
 {
-       const VkOffset3D        srcOffset       = region.imageCopy.srcOffset;
-       const VkOffset3D        dstOffset       = region.imageCopy.dstOffset;
-       const 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))
        {
@@ -1025,7 +1162,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();
@@ -1045,7 +1184,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()));
        }
 
@@ -1064,7 +1203,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()));
        }
 }
@@ -1131,23 +1270,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));
@@ -1208,7 +1333,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();
@@ -1220,11 +1347,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 |
@@ -1236,7 +1363,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()));
        }
 
@@ -1255,7 +1382,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()));
        }
 }
@@ -1414,7 +1541,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();
@@ -1434,7 +1563,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()));
        }
 
@@ -1445,11 +1574,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 |
@@ -1461,7 +1590,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()));
        }
 }
@@ -1593,10 +1722,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;
@@ -1608,7 +1740,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();
@@ -1661,11 +1795,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 |
@@ -1677,7 +1811,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()));
        }
 
@@ -1688,11 +1822,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 |
@@ -1704,7 +1838,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()));
        }
 }
@@ -1744,7 +1878,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;
@@ -1764,7 +1898,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;
@@ -1787,11 +1921,10 @@ 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);
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
 
        de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
 
@@ -1850,38 +1983,16 @@ 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))
        {
@@ -1891,11 +2002,9 @@ bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBuffer
                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);
@@ -1911,116 +2020,373 @@ 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;
 
-                       if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT))
+                       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);
+
+                       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))
-               {
-                       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();
+tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
+{
+       const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
+       const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
 
-                       if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT))
-                       {
-                               return tcu::TestStatus::fail("CopiesAndBlitting test");
-                       }
-               }
+       if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
+       {
+               return getFormatThreshold(format);
        }
-       else
+       else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+                        channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
        {
-               if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT))
+               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)
                {
-                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+                       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();
        }
-
-       return tcu::TestStatus::pass("CopiesAndBlitting test");
 }
 
-tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
+bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&       source,
+                                                         const tcu::ConstPixelBufferAccess&    result,
+                                                         const tcu::PixelBufferAccess&                 errorMask,
+                                                         const std::vector<CopyRegion>&                regions)
 {
-       return isSRGB(format) ? linearToSRGB(color) : color;
-}
+       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;
 
-void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
-{
-       DE_ASSERT(filter == tcu::Sampler::LINEAR);
-       DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
+       {
+               const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
+               const tcu::Vec4         srcMaxDiff      = getFloatOrFixedPointFormatThreshold(source.getFormat());
+               const tcu::Vec4         dstMaxDiff      = getFloatOrFixedPointFormatThreshold(result.getFormat());
 
-       tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
-                                       filter, filter, 0.0f, false);
+               precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
+               precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
+       }
 
-       float sX = (float)regionExtent.x / (float)dst.getWidth();
-       float sY = (float)regionExtent.y / (float)dst.getHeight();
+       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())
+       };
 
-       for (int y = 0; y < dst.getHeight(); y++)
-       for (int x = 0; x < dst.getWidth(); x++)
-               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);
+       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);
 }
 
-void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
+bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
+                                                       const tcu::ConstPixelBufferAccess&      result,
+                                                       const tcu::PixelBufferAccess&           errorMask,
+                                                       const std::vector<CopyRegion>&          regions)
 {
-       DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
+       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;
 
-       tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
-                                                filter, filter, 0.0f, false);
+       {
+               const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
+               const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
 
-       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();
+               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;
+               }
+       }
 
-       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;
+       // 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();
 
-       const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
-       const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
+       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
 
-       if (dst.getDepth() == 1 && src.getDepth() == 1)
+       const struct Capture
        {
-               for (int y = 0; y < dst.getHeight(); ++y)
-               for (int x = 0; x < dst.getWidth(); ++x)
+               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 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);
+                       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);
                }
-       }
-       else
-       {
-               for (int z = 0; z < dst.getDepth(); ++z)
+       } 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 (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               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 // NEAREST filtering
+       {
+               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               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("Pass");
+}
+
+tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
+{
+       return isSRGB(format) ? linearToSRGB(color) : color;
+}
+
+void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
+{
+       DE_ASSERT(filter == tcu::Sampler::LINEAR);
+       DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
+
+       tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
+                                       filter, filter, 0.0f, false);
+
+       float sX = (float)regionExtent.x / (float)dst.getWidth();
+       float sY = (float)regionExtent.y / (float)dst.getHeight();
+
+       for (int y = 0; y < dst.getHeight(); y++)
+       for (int x = 0; x < dst.getWidth(); x++)
+               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)
                {
@@ -2253,7 +2619,9 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
        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();
@@ -2309,10 +2677,10 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                        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)
@@ -2322,7 +2690,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                                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    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
+                               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;
                        }
@@ -2333,7 +2701,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                                colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
                                m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
                                // Allocate and bind color image memory.
-                               m_multisampledCopyImageAlloc    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
+                               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;
                        }
@@ -2366,7 +2734,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                };
 
                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()));
        }
 
@@ -2460,6 +2828,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
        }
 
+       // 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);
@@ -2486,8 +2855,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                };
 
                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.
@@ -2498,7 +2866,6 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
        {
                Move<VkFramebuffer>             framebuffer;
                Move<VkImageView>               sourceAttachmentView;
-               const VkExtent3D                extent3D = getExtent3D(m_params.src.image);
 
                // Create color attachment view.
                {
@@ -2520,20 +2887,20 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                {
                        const VkImageView                               attachments[1]          =
                        {
-                               *sourceAttachmentView,
+                                       *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;
-                               extent3D.width,                                                         // deUint32                                             width;
-                               extent3D.height,                                                        // deUint32                                             height;
-                               1u                                                                                      // deUint32                                             layers;
+                                       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);
@@ -2565,9 +2932,9 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
 
                        const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
                        {
-                               0u,                                                                     // deUint32                             binding;
-                               sizeof(tcu::Vec4),                                      // deUint32                             stride;
-                               VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
+                                       0u,                                                                     // deUint32                             binding;
+                                       sizeof(tcu::Vec4),                                      // deUint32                             stride;
+                                       VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
                        };
 
                        const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[1]     =
@@ -2582,13 +2949,13 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
 
                        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;
+                               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                        =
@@ -2602,74 +2969,74 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
 
                        const VkViewport        viewport        =
                        {
-                               0.0f,                                                   // float        x;
-                               0.0f,                                                   // float        y;
-                               (float)extent3D.width,  // float        width;
-                               (float)extent3D.height, // float        height;
-                               0.0f,                                                   // float        minDepth;
-                               1.0f                                                    // float        maxDepth;
+                               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;
-                               { extent3D.width, extent3D.height }     // VkExtent2D   extent;
+                               { 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;
+                               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;
+                               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;
+                               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;
+                               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;
+                               VK_COLOR_COMPONENT_G_BIT |
+                               VK_COLOR_COMPONENT_B_BIT |
+                               VK_COLOR_COMPONENT_A_BIT)               // VkChannelFlags       channelWriteMask;
                        };
 
                        const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams   =
@@ -2733,7 +3100,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                                *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
                                {
                                        { 0, 0 },
-                                       { extent3D.width, extent3D.height }
+                                       { m_params.src.image.extent.width, m_params.src.image.extent.height }
                                },                                                                                                              // VkRect2D                             renderArea;
                                1u,                                                                                                             // deUint32                             clearValueCount;
                                clearValues                                                                                             // const VkClearValue*  pClearValues;
@@ -2742,11 +3109,12 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                        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.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
 
                        vk.cmdEndRenderPass(*m_cmdBuffer);
                        VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
@@ -2766,20 +3134,20 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
        const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
 
        // 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_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));
+       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();
+       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();
 
        switch (m_options)
        {
@@ -2826,7 +3194,7 @@ 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;
@@ -2852,13 +3220,13 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
                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;
-                               getArraySize(m_params.dst.image)// deUint32                                     arraySize;
-                       }
+               {                                                                               // VkImageSubresourceRange      subresourceRange;
+                       getAspectFlags(dstTcuFormat),           // VkImageAspectFlags           aspectMask;
+                       0u,                                                                     // deUint32                                     baseMipLevel;
+                       1u,                                                                     // deUint32                                     mipLevels;
+                       0u,                                                                     // deUint32                                     baseArraySlice;
+                       getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
+               }
        };
 
        const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
@@ -2874,17 +3242,11 @@ 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);
 
-       submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
-
-       // check the result of resolving image
-       {
-               de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
+       de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
 
-               if (QP_TEST_RESULT_PASS != checkTestResult(resultTextureLevel->getAccess()).getCode())
-                       return tcu::TestStatus::fail("CopiesAndBlitting test");
-       }
-       return tcu::TestStatus::pass("CopiesAndBlitting test");
+       return checkTestResult(resultTextureLevel->getAccess());
 }
 
 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
@@ -2958,7 +3320,7 @@ void ResolveImageToImage::copyMSImageToMSImage (void)
 
        const VkImageMemoryBarrier              imageBarriers[]         =
        {
-               //// source image
+               // source image
                {
                        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
                        DE_NULL,                                                                        // const void*                          pNext;
@@ -3071,6 +3433,7 @@ void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollec
                "       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"
@@ -3090,521 +3453,50 @@ std::string getFormatCaseName (VkFormat format)
        return de::toLower(de::toString(getFormatStr(format)).substr(10));
 }
 
-void addCopyImageTestsAllFormats (tcu::TestCaseGroup*  testCaseGroup,
-                                                                 tcu::TestContext&             testCtx,
-                                                                 TestParams&                   params)
+std::string getImageLayoutCaseName (VkImageLayout layout)
 {
-       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,
-
-               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,
-
-               VK_FORMAT_UNDEFINED
-        };
-       const VkFormat  compatibleFormats256Bit[]               =
-       {
-               VK_FORMAT_R64G64B64A64_UINT,
-               VK_FORMAT_R64G64B64A64_SINT,
-               VK_FORMAT_R64G64B64A64_SFLOAT,
-
-               VK_FORMAT_UNDEFINED
-       };
-
-       const VkFormat* colorImageFormatsToTest[]               =
-       {
-               compatibleFormats8Bit,
-               compatibleFormats16Bit,
-               compatibleFormats24Bit,
-               compatibleFormats32Bit,
-               compatibleFormats48Bit,
-               compatibleFormats64Bit,
-               compatibleFormats96Bit,
-               compatibleFormats128Bit,
-               compatibleFormats192Bit,
-               compatibleFormats256Bit,
-       };
-       const size_t    numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
-
-       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
-       {
-               const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
-               for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
-               {
-                       params.src.image.format = compatibleFormats[srcFormatIndex];
-                       for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++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));
-                       }
-               }
-       }
-}
-
-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_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
-       };
-
-       const struct {
-               const VkFormat* compatibleFormats;
-               const bool              onlyNearest;
-       }       colorImageFormatsToTest[]                       =
-       {
-               { compatibleFormatsUInts,       true    },
-               { compatibleFormatsSInts,       true    },
-               { compatibleFormatsFloats,      false   },
-               { compatibleFormatsSrgb,        false   },
-       };
-       const size_t    numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
-
-       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
+       switch (layout)
        {
-               const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats;
-               const bool              onlyNearest                     = colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest;
-               for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
-               {
-                       params.src.image.format = compatibleFormats[srcFormatIndex];
-                       for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++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 << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format;
-
-                               params.filter                   = VK_FILTER_NEAREST;
-                               testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params));
-
-                               if (!onlyNearest)
-                               {
-                                       params.filter           = VK_FILTER_LINEAR;
-                                       testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params));
-                               }
-                       }
-               }
+               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 "";
        }
 }
 
-} // anonymous
+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};
 
-tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
+const VkImageSubresourceLayers defaultSourceLayer              =
 {
-       de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests  (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
-
-       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"));
-
-       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"));
-
-       de::MovePtr<tcu::TestCaseGroup> resolveImageTests               (new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image"));
-
-       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;
-       };
+       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+       0u,                                                     // uint32_t                             mipLevel;
+       0u,                                                     // uint32_t                             baseArrayLayer;
+       1u,                                                     // uint32_t                             layerCount;
+};
 
-       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,
-       };
+void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx       = group->getTestContext();
 
-       // Copy image to image testcases.
        {
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               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        =
@@ -3622,17 +3514,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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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        =
@@ -3650,17 +3545,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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UINT;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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        =
@@ -3678,17 +3576,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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_D32_SFLOAT;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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 =
@@ -3713,17 +3614,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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_S8_UINT;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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 =
@@ -3748,115 +3652,809 @@ 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));
        }
+}
 
-       {
-               // Test Color formats.
-               {
-                       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;
+struct CopyColorTestParams
+{
+       TestParams              params;
+       const VkFormat* compatibleFormats;
+};
 
-                       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;
-                               };
+void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
+{
+       const VkImageLayout copySrcLayouts[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout copyDstLayouts[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
 
-                               CopyRegion      imageCopy;
-                               imageCopy.imageCopy     = testCopy;
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
+       {
+               params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
 
-                               params.regions.push_back(imageCopy);
-                       }
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
+               {
+                       params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
 
-                       addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params);
+                       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));
                }
+       }
+}
 
-               // Test Depth and Stencil formats.
-               {
-                       const std::string       description     ("Copy image to image with depth/stencil formats ");
-                       const std::string       testName        ("depth_stencil");
+bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams)
+{
+       bool result = true;
 
-                       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
-                       {
-                               TestParams params;
+       if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
 
-                               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;
-                               std::ostringstream      oss;
-                               oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
+               result =
+                       de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
+                       de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
+       }
 
-                               const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
-                               const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
+       return result;
+}
 
-                               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};
+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 (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);
-                                       }
-                               }
+               if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
+                       continue;
 
-                               imgToImgAllFormatsTests->addChild(new CopyImageToImageTestCase(testCtx, oss.str(), description, 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);
        }
-       imageToImageTests->addChild(imgToImgSimpleTests.release());
-       imageToImageTests->addChild(imgToImgAllFormatsTests.release());
-
-       // Copy image to buffer testcases.
-       {
-               TestParams      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.buffer.size          = defaultSize * defaultSize;
+}
 
-               const VkBufferImageCopy bufferImageCopy =
-               {
-                       0u,                                                                                     // VkDeviceSize                         bufferOffset;
-                       0u,                                                                                     // uint32_t                                     bufferRowLength;
+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,
+
+       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,
+
+       VK_FORMAT_UNDEFINED
+};
+const VkFormat compatibleFormats256Bit[]       =
+{
+       VK_FORMAT_R64G64B64A64_UINT,
+       VK_FORMAT_R64G64B64A64_SINT,
+       VK_FORMAT_R64G64B64A64_SFLOAT,
+
+       VK_FORMAT_UNDEFINED
+};
+
+const VkFormat*        colorImageFormatsToTest[]       =
+{
+       compatibleFormats8Bit,
+       compatibleFormats16Bit,
+       compatibleFormats24Bit,
+       compatibleFormats32Bit,
+       compatibleFormats48Bit,
+       compatibleFormats64Bit,
+       compatibleFormats96Bit,
+       compatibleFormats128Bit,
+       compatibleFormats192Bit,
+       compatibleFormats256Bit,
+};
+
+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 =
+               {
+                       defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
+                       {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
+                       defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
+                       {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
+                       {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
+               };
+
+               CopyRegion      imageCopy;
+               imageCopy.imageCopy = testCopy;
+
+               params.regions.push_back(imageCopy);
+       }
+
+       if (allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
+               for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
+                       dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
+       }
+
+       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)
+               {
+                       params.src.image.format = compatibleFormats[srcFormatIndex];
+                       if (!isSupportedByFramework(params.src.image.format))
+                               continue;
+
+                       CopyColorTestParams     testParams;
+                       testParams.params                               = params;
+                       testParams.compatibleFormats    = compatibleFormats;
+
+                       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[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+       const VkImageLayout copyDstLayouts[]            =
+       {
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_IMAGE_LAYOUT_GENERAL
+       };
+
+       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)
+               {
+                       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;
+
+               {
+                       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;
@@ -3867,15 +4465,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
 
                params.regions.push_back(copyRegion);
 
-               imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
+               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.dst.buffer.size          = defaultSize * defaultSize;
+               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 =
                {
@@ -3891,15 +4491,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
 
                params.regions.push_back(copyRegion);
 
-               imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
+               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.dst.buffer.size          = defaultSize * defaultSize;
+               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;
@@ -3928,16 +4530,22 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(region);
                }
 
-               imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
+               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();
 
-       // Copy buffer to image testcases.
        {
                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.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 =
                {
@@ -3953,15 +4561,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
 
                params.regions.push_back(copyRegion);
 
-               bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
+               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.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;
@@ -3980,15 +4590,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                        params.regions.push_back(region);
                }
 
-               bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
+               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.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 =
                {
@@ -4004,14 +4616,19 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
 
                params.regions.push_back(copyRegion);
 
-               bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
+               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();
 
-       // Copy buffer to buffer testcases.
        {
                TestParams                      params;
                params.src.buffer.size  = defaultSize;
                params.dst.buffer.size  = defaultSize;
+               params.allocationKind   = allocationKind;
 
                const VkBufferCopy      bufferCopy      =
                {
@@ -4024,13 +4641,14 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                copyRegion.bufferCopy   = bufferCopy;
                params.regions.push_back(copyRegion);
 
-               bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
+               group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
        }
 
        {
                TestParams                      params;
                params.src.buffer.size  = defaultFourthSize;
                params.dst.buffer.size  = defaultFourthSize;
+               params.allocationKind   = allocationKind;
 
                const VkBufferCopy      bufferCopy      =
                {
@@ -4043,7 +4661,7 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                copyRegion.bufferCopy = bufferCopy;
                params.regions.push_back(copyRegion);
 
-               bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
+               group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
        }
 
        {
@@ -4051,6 +4669,7 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
                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++)
@@ -4067,1052 +4686,1590 @@ 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);
+       }
+
+       // 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 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       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
+
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, defaultSize, 0},
+                               {0, 0, 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));
        }
 
-       // Blitting testcases.
+       // Filter is VK_FILTER_LINEAR.
        {
-               const std::string       description     ("Blit without scaling (whole)");
-               const std::string       testName        ("whole");
-
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+               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));
 
-                       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)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
 
-               // Filter is VK_FILTER_NEAREST.
+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;
-
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[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));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, 0, 0},
+                               {0, defaultSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       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));
-               }
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-               // Filter is VK_FILTER_LINEAR.
-               {
-                       params.filter                   = VK_FILTER_LINEAR;
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+               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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, 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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, 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     ("Flipping x and y coordinates (whole)");
-               const std::string       testName        ("mirror_xy");
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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 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       =
                {
-                       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;
-                               {
-                                       {defaultSize, defaultSize, 1},
-                                       {0, 0, 0}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, defaultSize, 0},
+                               {defaultSize, 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;
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+               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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, 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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" +  getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, 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;
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+               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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, 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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, 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));
        }
+}
 
-       {
-               const std::string       description     ("Flipping x coordinates (whole)");
-               const std::string       testName        ("mirror_x");
+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       =
+               {
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
+
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
+       // Flipping y coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       const VkImageBlit                               imageBlit       =
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                        {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+                               {defaultHalfSize, 0, 0},
+                               {defaultSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[2];
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {defaultSize, 0, 0},
-                                       {0, defaultSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {defaultSize, 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.
+       // Flipping x coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       params.filter                   = VK_FILTER_NEAREST;
-
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, defaultHalfSize, 0},
+                               {defaultHalfSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[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));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {0, defaultSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[2];
+               };
 
-                       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));
-               }
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
+       }
 
-               // Filter is VK_FILTER_LINEAR.
+       // Flipping x and y coordinates.
+       {
+               const VkImageBlit                               imageBlit       =
                {
-                       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));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {defaultHalfSize, defaultHalfSize, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                           srcOffsets[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));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {defaultSize, defaultSize, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                           dstOffset[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));
-               }
+               CopyRegion      region;
+               region.imageBlit = imageBlit;
+               params.regions.push_back(region);
        }
 
+       // Filter is VK_FILTER_NEAREST.
        {
-               const std::string       description     ("Flipping Y coordinates (whole)");
-               const std::string       testName        ("mirror_y");
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
-
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, defaultSize, 1},
-                                       {defaultSize, 0, 0}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+               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));
 
-                       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)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
+       }
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+               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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, 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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, 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));
+       }
+}
 
-               // Filter is VK_FILTER_LINEAR.
+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;
-
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[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));
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       }                                       // VkOffset3D                                   dstOffset[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));
-               }
+               CopyRegion      region;
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
        }
 
+       // Filter is VK_FILTER_NEAREST.
        {
-               const std::string       description     ("Mirroring subregions in image (no flip ,y flip ,x flip, xy flip)");
-               const std::string       testName        ("mirror_subregions");
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
 
-               // No mirroring.
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+               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));
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+               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));
+       }
 
-                       CopyRegion      region;
-                       region.imageBlit = imageBlit;
-                       params.regions.push_back(region);
-               }
+       // Filter is VK_FILTER_LINEAR.
+       {
+               params.filter                                   = VK_FILTER_LINEAR;
+               const std::string description   = "Linear filter";
 
-               // Flipping y coordinates.
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {defaultHalfSize, 0, 0},
-                                       {defaultSize, defaultHalfSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {defaultHalfSize, defaultHalfSize, 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)" );
+               group->addChild(new BlittingTestCase(testCtx, 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)");
+               group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
+       }
+}
 
-               // Flipping x coordinates.
+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       =
                {
-                       const VkImageBlit                               imageBlit       =
+                       defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
                        {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, defaultHalfSize, 0},
-                                       {defaultHalfSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+                               {0, 0, 0},
+                               {defaultHalfSize, defaultHalfSize, 1}
+                       },                                      // VkOffset3D                                   srcOffsets[2];
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {defaultHalfSize, defaultHalfSize, 0},
-                                       {0, defaultSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+                       defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
+                       {
+                               {0, 0, 0},
+                               {defaultSize, defaultSize, 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 x and y coordinates.
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {defaultHalfSize, defaultHalfSize, 0},
-                                       {defaultSize, defaultSize, 1}
-                               },                                      // VkOffset3D                           srcOffsets[2];
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {defaultSize, defaultSize, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
-                               }                                       // VkOffset3D                           dstOffset[2];
-                       };
+               params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
 
-                       CopyRegion      region;
-                       region.imageBlit = imageBlit;
-                       params.regions.push_back(region);
-               }
+               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_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+               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;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+               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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, 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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, 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));
+       }
+}
 
-               // Filter is VK_FILTER_LINEAR.
+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       =
                {
-                       params.filter                   = VK_FILTER_LINEAR;
+                       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);
+       }
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+       // Filter is VK_FILTER_NEAREST.
+       {
+               params.filter                                   = VK_FILTER_NEAREST;
+               const std::string description   = "Nearest filter";
 
-                       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_R8G8B8A8_UNORM;
+               group->addChild(new BlittingTestCase(testCtx, "nearest", description, 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));
-               }
+               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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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 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},
-                                       {defaultSize, defaultSize, 1}
+                                       {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
+                                       {defaultSize - i, defaultSize - i, 1}
                                },                                      // VkOffset3D                                   srcOffsets[2];
 
                                defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
                                {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 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;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+               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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + 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)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, 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.filter                   = 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;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+               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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, 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)" + " (VK_FILTER_LINEAR)");
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, 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));
        }
+}
 
-       {
-               const std::string       description     ("Blit with scaling (whole, dst extent bigger)");
-               const std::string       testName        ("scaling_whole2");
+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);
+}
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultHalfExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+struct BlitColorTestParams
+{
+       TestParams              params;
+       const VkFormat* compatibleFormats;
+       bool                    onlyNearest;
+};
 
-               {
-                       const VkImageBlit                               imageBlit       =
-                       {
-                               defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultHalfSize, defaultHalfSize, 1}
-                               },                                      // VkOffset3D                                   srcOffsets[2];
+bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
+{
+       bool result = true;
 
-                               defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
-                               {
-                                       {0, 0, 0},
-                                       {defaultSize, defaultSize, 1}
-                               }                                       // VkOffset3D                                   dstOffset[2];
-                       };
+       if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
 
-                       CopyRegion      region;
-                       region.imageBlit        = imageBlit;
-                       params.regions.push_back(region);
-               }
+               result =
+                       de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
+                       de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
+       }
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+       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;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+               testParams.params.dst.image.format      = testParams.compatibleFormats[dstFormatIndex];
+               if (!isSupportedByFramework(testParams.params.dst.image.format))
+                       continue;
 
-               {
-                       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];
-                       };
+               if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
+                       continue;
 
-                       CopyRegion      region;
-                       region.imageBlit        = imageBlit;
-                       params.regions.push_back(region);
-               }
+               const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
+               addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
+       }
+}
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+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
+};
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+const VkFormat dedicatedAllocationBlittingFormatsToTest[]      =
+{
+       // compatibleFormatsUInts
+       VK_FORMAT_R8_UINT,
+       VK_FORMAT_R64G64B64A64_UINT,
 
-                       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));
+       // compatibleFormatsSInts
+       VK_FORMAT_R8_SINT,
+       VK_FORMAT_R64G64B64A64_SINT,
 
-                       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));
-               }
+       // compatibleFormatsFloats
+       VK_FORMAT_R4G4_UNORM_PACK8,
+       VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
 
-               // Filter is VK_FILTER_LINEAR.
-               {
-                       params.filter                   = VK_FILTER_LINEAR;
+       // compatibleFormatsSrgb
+       VK_FORMAT_R8_SRGB,
+       VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+};
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", 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   },
+       };
 
-                       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));
+       const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
 
-                       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));
-               }
-       }
+       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;
 
+       CopyRegion      region;
+       for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
        {
-               const std::string       description     ("Blit without scaling (partial)");
-               const std::string       testName        ("without_scaling_partial");
-
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.extent         = defaultExtent;
+               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];
+               };
+               region.imageBlit        = imageBlit;
+               params.regions.push_back(region);
+       }
+       for (int i = 0; i < defaultSize; i += defaultFourthSize)
+       {
+               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);
+       }
 
-               // Filter is VK_FILTER_NEAREST.
-               {
-                       params.filter                   = VK_FILTER_NEAREST;
+       if (allocationKind == ALLOCATION_KIND_DEDICATED)
+       {
+               const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
+               for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
+                       dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
+       }
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
+       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.src.image.format = compatibleFormats[srcFormatIndex];
+                       if (!isSupportedByFramework(params.src.image.format))
+                               continue;
 
-                       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));
+                       BlitColorTestParams             testParams;
+                       testParams.params                               = params;
+                       testParams.compatibleFormats    = compatibleFormats;
+                       testParams.onlyNearest                  = onlyNearest;
 
-                       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 std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
+                       addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
                }
+       }
+}
 
-               // Filter is VK_FILTER_LINEAR.
-               {
-                       params.filter                   = VK_FILTER_LINEAR;
+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
+       };
+
+       for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
+       {
+               params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
 
-                       params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
-                       blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
+               for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
+               {
+                       params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
+                       params.filter                                           = VK_FILTER_NEAREST;
 
-                       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));
+                       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_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.imageType      = VK_IMAGE_TYPE_2D;
-                       params.src.image.extent         = defaultExtent;
-                       params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-                       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)
                {
-                       for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
+                       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))
                        {
-                               TestParams params;
-
-                               params.src.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.imageType      = VK_IMAGE_TYPE_2D;
-                               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);
                        }
                }
+
+               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);
        }
-       blittingImageTests->addChild(blitImgSimpleTests.release());
-       blittingImageTests->addChild(blitImgAllFormatsTests.release());
+}
 
-       // 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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = resolveExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = resolveExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               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)
-               {
-                       params.samples = samples[samplesIndex];
-                       std::ostringstream caseName;
-                       caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
-                       resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
-               }
        }
 
+       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));
+       }
+}
 
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = resolveExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.dst.image.extent         = resolveExtent;
+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     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // uint32_t                             mipLevel;
+                       0u,                                                     // 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_MS_IMAGE));
+       }
+}
 
-               for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
+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     =
                {
-                       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;
+                       layerNdx,                                               // 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        ("whole_copy_before_resolving");
-
-               TestParams                      params;
-               params.src.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent         = defaultExtent;
-               params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
-               params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
-               params.dst.image.extent         = defaultExtent;
+               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     =
                {
-                       const VkImageSubresourceLayers  sourceLayer     =
-                       {
-                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
-                               0u,                                                     // uint32_t                             mipLevel;
-                               0u,                                                     // uint32_t                             baseArrayLayer;
-                               1u                                                      // uint32_t                             layerCount;
-                       };
+                       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 VkImageResolve                    testResolve     =
-                       {
-                               sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
-                               {0, 0, 0},                      // VkOffset3D                           srcOffset;
-                               sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
-                               {0, 0, 0},                      // VkOffset3D                           dstOffset;
-                               defaultExtent,          // VkExtent3D                           extent;
-                       };
+       const VkExtent3D imageExtents[]         =
+       {
+               { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
+               { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
+               { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
+       };
 
-                       CopyRegion      imageResolve;
-                       imageResolve.imageResolve       = testResolve;
-                       params.regions.push_back(imageResolve);
+       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, COPY_MS_IMAGE_TO_MS_IMAGE));
+                       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));
                }
        }
+}
 
-       {
-               const std::string       description     ("Resolve from image to image");
-               const std::string       testName        ("whole_array_image");
+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);
+}
 
-               TestParams                      params;
-               params.src.image.imageType              = VK_IMAGE_TYPE_2D;
-               params.src.image.format                 = VK_FORMAT_R8G8B8A8_UNORM;
-               params.src.image.extent                 = defaultExtent;
-               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;
+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);
+}
 
-               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;
-                       };
+void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group)
+{
+       addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED);
+}
 
-                       const VkImageResolve                    testResolve     =
-                       {
-                               sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
-                               {0, 0, 0},                      // VkOffset3D                           srcOffset;
-                               sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
-                               {0, 0, 0},                      // VkOffset3D                           dstOffset;
-                               defaultExtent,          // VkExtent3D                           extent;
-                       };
+void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
+{
+       addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED);
+}
 
-                       CopyRegion      imageResolve;
-                       imageResolve.imageResolve       = testResolve;
-                       params.regions.push_back(imageResolve);
-               }
+} // anonymous
 
-               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, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
-               }
-       }
+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();
 }