Improve coverage of MSAA copies
authorVihanakangas <venni.ihanakangas@siru.fi>
Wed, 13 Oct 2021 12:10:41 +0000 (15:10 +0300)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Sat, 6 Nov 2021 20:12:47 +0000 (20:12 +0000)
This commit adds tests for copying with separate layers
along with tests for copying multiple regions.

New tests:

dEQP-VK.api.copy_and_blit.*.resolve_image.copy_with_regions_before_resolving.*
dEQP-VK.api.copy_and_blit.*.resolve_image.layer_copy_before_resolving.*

Affects:

dEQP-VK.api.copy_and_blit.*.resolve_image.*

Components: Vulkan

VK-GL-CTS issue: 3071

Change-Id: I4889383314125516a951c6034b95425d806e25fc

android/cts/master/vk-master-2021-03-01/api.txt
android/cts/master/vk-master/api.txt
external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
external/vulkancts/mustpass/master/vk-default/api.txt

index 4a043bf..b9a8bdc 100644 (file)
@@ -70714,6 +70714,18 @@ dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.6
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer_with_offset.0_0
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer_with_offset.0_1
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer_with_offset.0_2
@@ -82063,6 +82075,18 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_be
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.image_to_image.simple_tests.partial_image_npot_diff_format_clear
 dEQP-VK.api.copy_and_blit.copy_commands2.image_to_image.simple_tests.partial_image_pot_diff_format_clear
 dEQP-VK.api.copy_and_blit.copy_commands2.image_to_image.simple_tests.partial_image_npot_diff_format_noclear
@@ -93348,6 +93372,18 @@ dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_r
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.image_clearing.core.clear_color_image.1d.optimal.single_layer.r4g4_unorm_pack8_multiple_subresourcerange
 dEQP-VK.api.image_clearing.core.clear_color_image.1d.optimal.single_layer.r4g4_unorm_pack8_clamp_input
 dEQP-VK.api.image_clearing.core.clear_color_image.1d.optimal.single_layer.r4g4_unorm_pack8_clamp_input_multiple_subresourcerange
index b735eb3..e51cd27 100644 (file)
@@ -146447,6 +146447,18 @@ dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.6
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.8_bit
@@ -167427,6 +167439,18 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_be
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.8_bit
@@ -188343,6 +188367,18 @@ dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_r
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.8_bit
index 7ae29f6..7c94add 100644 (file)
@@ -5397,7 +5397,11 @@ private:
 
 // Resolve image to image.
 
-enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
+enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION,
+                                                               COPY_MS_IMAGE_TO_MS_IMAGE,
+                                                               COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
+                                                               COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
+                                                               COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION};
 class ResolveImageToImage : public CopiesAndBlittingTestInstance
 {
 public:
@@ -5469,6 +5473,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                        VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
                        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                                                                             // VkImageUsageFlags            usage;
                                | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+                               | VK_IMAGE_USAGE_TRANSFER_DST_BIT
                                | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
                        VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
                        1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
@@ -5484,6 +5489,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
 
                switch (m_options)
                {
+                       case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
                        case COPY_MS_IMAGE_TO_MS_IMAGE:
                        {
                                colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
@@ -5493,7 +5499,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                                VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
                                break;
                        }
-
+                       case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
                        case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
                        {
                                colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
@@ -5537,27 +5543,60 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
        }
 
-       // Barriers for copying image to buffer
-       VkImageMemoryBarrier            srcImageBarrier         =
+       // Barriers for image clearing.
+       std::vector<VkImageMemoryBarrier> srcImageBarriers;
+
+       const VkImageMemoryBarrier m_multisampledImageBarrier =
        {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
                DE_NULL,                                                                        // const void*                          pNext;
                0u,                                                                                     // VkAccessFlags                        srcAccessMask;
                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
                VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
-               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
                m_multisampledImage.get(),                                      // VkImage                                      image;
                {                                                                                       // VkImageSubresourceRange      subresourceRange;
-                       VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
-                       0u,                                                                     // deUint32                             baseMipLevel;
-                       1u,                                                                     // deUint32                             mipLevels;
-                       0u,                                                                     // deUint32                             baseArraySlice;
-                       getArraySize(m_params.src.image)        // deUint32                             arraySize;
+                       VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
+                       0u,                                                                             // deUint32                             baseMipLevel;
+                       1u,                                                                             // deUint32                             mipLevels;
+                       0u,                                                                             // deUint32                             baseArraySlice;
+                       getArraySize(m_params.src.image)                // deUint32                             arraySize;
+               }
+       };
+       const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+               DE_NULL,                                                                        // const void*                          pNext;
+               0u,                                                                                     // VkAccessFlags                        srcAccessMask;
+               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
+               VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+               m_multisampledCopyImage.get(),                          // VkImage                                      image;
+               {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                       VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
+                       0u,                                                                             // deUint32                             baseMipLevel;
+                       1u,                                                                             // deUint32                             mipLevels;
+                       0u,                                                                             // deUint32                             baseArraySlice;
+                       getArraySize(m_params.dst.image)                // deUint32                             arraySize;
                }
        };
 
+       // Only use one barrier if no options have been given.
+       if (m_options != DE_NULL)
+       {
+               srcImageBarriers.push_back(m_multisampledImageBarrier);
+               srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
+
+       }
+       else
+       {
+               srcImageBarriers.push_back(m_multisampledImageBarrier);
+       }
+
        // Create render pass.
        {
                const VkAttachmentDescription   attachmentDescriptions[1]       =
@@ -5570,8 +5609,8 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                                VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
                                VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
                                VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
-                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
-                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                                        initialLayout;
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL            // VkImageLayout                                        finalLayout;
                        },
                };
 
@@ -5666,18 +5705,20 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                Move<VkFramebuffer>             framebuffer;
                Move<VkImageView>               sourceAttachmentView;
 
+               uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
+
                // Create color attachment view.
                {
                        const VkImageViewCreateInfo     colorAttachmentViewParams       =
                        {
-                               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
-                               DE_NULL,                                                                                                // const void*                          pNext;
-                               0u,                                                                                                             // VkImageViewCreateFlags       flags;
-                               *m_multisampledImage,                                                                   // VkImage                                      image;
-                               VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
-                               m_params.src.image.format,                                                              // VkFormat                                     format;
-                               componentMappingRGBA,                                                                   // VkComponentMapping           components;
-                               { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+                               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                       // VkStructureType                      sType;
+                               DE_NULL,                                                                                                        // const void*                          pNext;
+                               0u,                                                                                                                     // VkImageViewCreateFlags       flags;
+                               *m_multisampledImage,                                                                           // VkImage                                      image;
+                               VK_IMAGE_VIEW_TYPE_2D,                                                                          // VkImageViewType                      viewType;
+                               m_params.src.image.format,                                                                      // VkFormat                                     format;
+                               componentMappingRGBA,                                                                           // VkComponentMapping           components;
+                               { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u }       // VkImageSubresourceRange      subresourceRange;
                        };
                        sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
                }
@@ -5745,7 +5786,30 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c
                // Create command buffer
                {
                        beginCommandBuffer(vk, *m_cmdBuffer, 0u);
-                       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);
+
+                       // Change the image layouts.
+                       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, uint32_t(srcImageBarriers.size()), srcImageBarriers.data());
+
+                       if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
+                       {
+                               // Clear the 'm_multisampledImage'.
+                               {
+                                       const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
+                                       const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
+                                       vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
+                               }
+
+                               // Clear the 'm_multisampledCopyImage' with different color.
+                               {
+                                       const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
+                                       const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
+                                       vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
+
+                                       const auto postClearMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT);
+                                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 1u, &postClearMemoryBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 0u, (const VkImageMemoryBarrier*)DE_NULL);
+                               }
+                       }
+
                        beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
 
                        const VkDeviceSize      vertexBufferOffset      = 0u;
@@ -5792,9 +5856,11 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
 
        switch (m_options)
        {
+               case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
                case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
                        // Duplicate the multisampled image to a multisampled image array
                        sourceArraySize = getArraySize(m_params.dst.image); // fall through
+               case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
                case COPY_MS_IMAGE_TO_MS_IMAGE:
                        copyMSImageToMSImage(sourceArraySize);
                        sourceImage     = m_multisampledCopyImage.get();
@@ -5809,16 +5875,46 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
 
        std::vector<VkImageResolve>             imageResolves;
        std::vector<VkImageResolve2KHR> imageResolves2KHR;
-       for (deUint32 i = 0; i < m_params.regions.size(); i++)
+       for (CopyRegion region : m_params.regions)
        {
-               if (m_params.extensionUse == EXTENSION_USE_NONE)
+               // If copying multiple regions, make sure that the same regions are
+               // used for resolving as the ones used for copying.
+               if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
                {
-                       imageResolves.push_back(m_params.regions[i].imageResolve);
+                       VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
+                                                                               getExtent3D(m_params.src.image).height / 2,
+                                                                               getExtent3D(m_params.src.image).depth};
+
+                       const VkImageResolve imageResolve =
+                       {
+                               region.imageResolve.srcSubresource,             // VkImageSubresourceLayers     srcSubresource;
+                               region.imageResolve.dstOffset,                  // VkOffset3D                           srcOffset;
+                               region.imageResolve.dstSubresource,             // VkImageSubresourceLayers     dstSubresource;
+                               region.imageResolve.dstOffset,                  // VkOffset3D                           dstOffset;
+                               partialExtent,                                                  // VkExtent3D                           extent;
+                       };
+
+                       if (m_params.extensionUse == EXTENSION_USE_NONE)
+                       {
+                               imageResolves.push_back(imageResolve);
+                       }
+                       else
+                       {
+                               DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+                               imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
+                       }
                }
                else
                {
-                       DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
-                       imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
+                       if (m_params.extensionUse == EXTENSION_USE_NONE)
+                       {
+                               imageResolves.push_back(region.imageResolve);
+                       }
+                       else
+                       {
+                               DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+                               imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
+                       }
                }
        }
 
@@ -5914,7 +6010,7 @@ tcu::TestStatus ResolveImageToImage::iterate (void)
 
        de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
 
-       if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
+       if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
        {
                // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
                // resolving the image and giving every sample the same value.
@@ -5931,13 +6027,33 @@ tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAcces
        const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel[0]->getAccess();
        const float                                                     fuzzyThreshold  = 0.01f;
 
-       for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
+       if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
        {
-               const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
-               const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+               // Check that all the layers that have not been written to are solid white.
+               tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
+               for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
+               {
+                       const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+                       if(resultSub.getPixel(0, 0) != expectedColor)
+                               return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
+               }
+
+               // Check that the layer that has been copied to is the same as the layer that has been copied from.
+               const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
+               const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
                if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
                        return tcu::TestStatus::fail("CopiesAndBlitting test");
        }
+       else
+       {
+               for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
+               {
+                       const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
+                       const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+                       if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
+       }
 
        return tcu::TestStatus::pass("CopiesAndBlitting test");
 }
@@ -5970,7 +6086,7 @@ tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
                                auto&   alloc                           = m_context.getDefaultAllocator();
        const           auto    currentLayout           = m_params.src.image.operationLayout;
        const           auto    numDstLayers            = getArraySize(m_params.dst.image);
-       const           auto    numInputAttachments     = numDstLayers + 1u; // For the source image.
+       const           auto    numInputAttachments     = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
        constexpr       auto    numSets                         = 2u; // 1 for the output buffer, 1 for the input attachments.
        const           auto    fbWidth                         = m_params.src.image.extent.width;
        const           auto    fbHeight                        = m_params.src.image.extent.height;
@@ -6096,13 +6212,23 @@ tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
        std::vector<Move<VkImageView>>  imageViews;
        std::vector<VkImageView>                imageViewsRaw;
 
-       imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
-       for (deUint32 i = 0u; i < numDstLayers; ++i)
+
+       if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
+       {
+               imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
+               imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
+       }
+       else
        {
-               const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
-               imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
+               imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
+               for (deUint32 i = 0u; i < numDstLayers; ++i)
+               {
+                       const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
+                       imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
+               }
        }
 
+
        imageViewsRaw.reserve(imageViews.size());
        std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
 
@@ -6257,13 +6383,13 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
        std::vector<VkImageCopy>                imageCopies;
        std::vector<VkImageCopy2KHR>    imageCopies2KHR;
 
-       for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
+       if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
        {
                const VkImageSubresourceLayers  sourceSubresourceLayers =
                {
                        getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
                        0u,                                                             // deUint32                             mipLevel;
-                       0u,                                                             // deUint32                             baseArrayLayer;
+                       2u,                                                             // deUint32                             baseArrayLayer;
                        1u                                                              // deUint32                             layerCount;
                };
 
@@ -6271,7 +6397,7 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
                {
                        getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
                        0u,                                                             // deUint32                             mipLevel;
-                       layerNdx,                                               // deUint32                             baseArrayLayer;
+                       4u,                                                             // deUint32                             baseArrayLayer;
                        1u                                                              // deUint32                             layerCount;
                };
 
@@ -6281,7 +6407,7 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
                        {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
                        destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
                        {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
-                        getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
+                       getExtent3D(m_params.src.image),        // VkExtent3D                           extent;
                };
 
                if (m_params.extensionUse == EXTENSION_USE_NONE)
@@ -6294,6 +6420,74 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
                        imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
                }
        }
+       else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
+       {
+               VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
+                                                                       getExtent3D(m_params.src.image).height / 2,
+                                                                       getExtent3D(m_params.src.image).depth};
+
+               for (CopyRegion region : m_params.regions)
+               {
+                       const VkImageCopy                               imageCopy       =
+                       {
+                               region.imageResolve.srcSubresource,             // VkImageSubresourceLayers     srcSubresource;
+                               region.imageResolve.srcOffset,                  // VkOffset3D                           srcOffset;
+                               region.imageResolve.dstSubresource,             // VkImageSubresourceLayers     dstSubresource;
+                               region.imageResolve.dstOffset,                  // VkOffset3D                           dstOffset;
+                               partialExtent,                                                  // VkExtent3D                           extent;
+                       };
+
+                       if (m_params.extensionUse == EXTENSION_USE_NONE)
+                       {
+                               imageCopies.push_back(imageCopy);
+                       }
+                       else
+                       {
+                               DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+                               imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
+                       }
+               }
+       }
+       else
+       {
+               for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
+               {
+                       const VkImageSubresourceLayers  sourceSubresourceLayers =
+                       {
+                               getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
+                               0u,                                                             // deUint32                             mipLevel;
+                               0u,                                                             // deUint32                             baseArrayLayer;
+                               1u                                                              // deUint32                             layerCount;
+                       };
+
+                       const VkImageSubresourceLayers  destinationSubresourceLayers    =
+                       {
+                               getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
+                               0u,                                                             // deUint32                             mipLevel;
+                               layerNdx,                                               // deUint32                             baseArrayLayer;
+                               1u                                                              // deUint32                             layerCount;
+                       };
+
+                       const VkImageCopy                               imageCopy       =
+                       {
+                               sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
+                               {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
+                               destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
+                               {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
+                               getExtent3D(m_params.src.image),        // VkExtent3D                           extent;
+                       };
+
+                       if (m_params.extensionUse == EXTENSION_USE_NONE)
+                       {
+                               imageCopies.push_back(imageCopy);
+                       }
+                       else
+                       {
+                               DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+                               imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
+                       }
+               }
+       }
 
        const VkImageMemoryBarrier              imageBarriers[]         =
        {
@@ -6303,7 +6497,7 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
                        DE_NULL,                                                                        // const void*                          pNext;
                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
                        m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
@@ -6322,7 +6516,7 @@ void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
                        DE_NULL,                                                                        // const void*                          pNext;
                        0,                                                                                      // VkAccessFlags                        srcAccessMask;
                        VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
                        m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
                        VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
@@ -6464,7 +6658,7 @@ void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollec
                "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
                "}\n");
 
-       if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
+       if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
        {
                // The shader verifies all layers in the copied image are the same as the source image.
                // This needs an image view per layer in the copied image.
@@ -6488,10 +6682,18 @@ void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollec
                        ;
 
                const auto dstLayers = getArraySize(m_params.dst.image);
-               for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+
+               if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
                {
-                       const auto i = layerNdx + 1u;
-                       verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
+                       verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
+               }
+               else
+               {
+                       for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+                       {
+                               const auto i = layerNdx + 1u;
+                               verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
+                       }
                }
 
                // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
@@ -6503,17 +6705,25 @@ void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollec
                        << "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
                        ;
 
-               for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+               std::ostringstream testCondition;
+               if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
                {
-                       const auto i = layerNdx + 1u;
-                       verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
+                       verificationShader << "        vec4 copy = subpassLoad(attachment1, sampleID);\n";
+                       testCondition << "orig == copy";
                }
-
-               std::ostringstream testCondition;
-               for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+               else
                {
-                       const auto i = layerNdx + 1u;
-                       testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
+                       for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+                       {
+                               const auto i = layerNdx + 1u;
+                               verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
+                       }
+
+                       for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+                       {
+                               const auto i = layerNdx + 1u;
+                               testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
+                       }
                }
 
                verificationShader
@@ -11991,6 +12201,132 @@ void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup
        }
 }
 
+void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
+{
+       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.extent.depth           = 5u;
+       params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
+       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.tiling                         = VK_IMAGE_TILING_OPTIMAL;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+       params.extensionUse                                     = extensionUse;
+
+       for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // deUint32                             mipLevel;
+                       layerNdx,                                               // deUint32                             baseArrayLayer;
+                       1u                                                              // deUint32                             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)
+       {
+               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_LAYER_TO_MS_IMAGE));
+       }
+}
+
+void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
+{
+       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.tiling                         = VK_IMAGE_TILING_OPTIMAL;
+       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.tiling                         = VK_IMAGE_TILING_OPTIMAL;
+       params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       params.allocationKind                           = allocationKind;
+       params.extensionUse                                     = extensionUse;
+
+       int32_t         imageHalfWidth  = getExtent3D(params.src.image).width / 2;
+       int32_t         imageHalfHeight = getExtent3D(params.src.image).height / 2;
+       VkExtent3D      halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
+
+       // Lower right corner to lower left corner.
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // deUint32                             mipLevel;
+                       0u,                                                             // deUint32                             baseArrayLayer;
+                       1u                                                              // deUint32                             layerCount;
+               };
+
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,                                                    // VkImageSubresourceLayers     srcSubresource;
+                       {imageHalfWidth, imageHalfHeight, 0},   // VkOffset3D                           srcOffset;
+                       sourceLayer,                                                    // VkImageSubresourceLayers     dstSubresource;
+                       {0, imageHalfHeight, 0},                                // VkOffset3D                           dstOffset;
+                       halfImageExtent,                                                                        // VkExtent3D                           extent;
+               };
+
+               CopyRegion      imageResolve;
+               imageResolve.imageResolve       = testResolve;
+               params.regions.push_back(imageResolve);
+       }
+
+       // Upper right corner to lower right corner.
+       {
+               const VkImageSubresourceLayers  sourceLayer     =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // deUint32                             mipLevel;
+                       0u,                                                             // deUint32                             baseArrayLayer;
+                       1u                                                              // deUint32                             layerCount;
+               };
+
+               const VkImageResolve                    testResolve     =
+               {
+                       sourceLayer,                                                    // VkImageSubresourceLayers     srcSubresource;
+                       {imageHalfWidth, 0, 0},                                 // VkOffset3D                           srcOffset;
+                       sourceLayer,                                                    // VkImageSubresourceLayers     dstSubresource;
+                       {imageHalfWidth, imageHalfHeight, 0},   // VkOffset3D                           dstOffset;
+                       halfImageExtent,                                                                        // 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];
+               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_MULTIREGION));
+       }
+}
+
 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
 {
        TestParams      params;
@@ -12182,6 +12518,8 @@ void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationK
        addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
        addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
        addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
+       addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
+       addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
        addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
        addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
        addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
index 56a1de5..0ce8b9f 100644 (file)
@@ -146446,6 +146446,18 @@ dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.6
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.core.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.core.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.core.resolve_image.whole_array_image.8_bit
@@ -167426,6 +167438,18 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_be
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.dedicated_allocation.resolve_image.whole_array_image.8_bit
@@ -188342,6 +188366,18 @@ dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_r
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_general_transfer_dst_optimal
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_general
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.diff_layout_copy_before_resolving.64_bit_transfer_src_optimal_transfer_dst_optimal
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.layer_copy_before_resolving.64_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.2_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.4_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.8_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.16_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.32_bit
+dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.copy_with_regions_before_resolving.64_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.2_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.4_bit
 dEQP-VK.api.copy_and_blit.copy_commands2.resolve_image.whole_array_image.8_bit