Merge "Merge Vulkan CTS 1.0.2.4 into aosp/master"
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015-2016 The Khronos Group Inc.
6  * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan Copies And Blitting Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktApiCopiesAndBlittingTests.hpp"
26
27 #include "deStringUtil.hpp"
28 #include "deUniquePtr.hpp"
29
30 #include "tcuImageCompare.hpp"
31 #include "tcuTexture.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuVectorType.hpp"
34 #include "tcuVectorUtil.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuTexLookupVerifier.hpp"
37
38 #include "vkImageUtil.hpp"
39 #include "vkMemUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vktTestCase.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 #include "vkTypeUtil.hpp"
47
48 #include <set>
49
50 namespace vkt
51 {
52
53 namespace api
54 {
55
56 namespace
57 {
58 enum MirrorMode
59 {
60         MIRROR_MODE_NONE = 0,
61         MIRROR_MODE_X = (1<<0),
62         MIRROR_MODE_Y = (1<<1),
63         MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
64
65         MIRROR_MODE_LAST
66 };
67
68 enum AllocationKind
69 {
70         ALLOCATION_KIND_SUBALLOCATED,
71         ALLOCATION_KIND_DEDICATED,
72 };
73
74 template <typename Type>
75 class BinaryCompare
76 {
77 public:
78         bool operator() (const Type& a, const Type& b) const
79         {
80                 return deMemCmp(&a, &b, sizeof(Type)) < 0;
81         }
82 };
83
84 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >    FormatSet;
85
86 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
87 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
88
89 using namespace vk;
90
91 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
92 {
93         VkImageAspectFlags      aspectFlag      = 0;
94         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
95         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
96
97         if (!aspectFlag)
98                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
99
100         return aspectFlag;
101 }
102
103 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
104 // except that it supports some formats that are not mappable to VkFormat.
105 // When we are checking combined depth and stencil formats, each aspect is
106 // checked separately, and in some cases we construct PBA with a format that
107 // is not mappable to VkFormat.
108 bool isFloatFormat (tcu::TextureFormat format)
109 {
110         return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
111 }
112
113 union CopyRegion
114 {
115         VkBufferCopy            bufferCopy;
116         VkImageCopy                     imageCopy;
117         VkBufferImageCopy       bufferImageCopy;
118         VkImageBlit                     imageBlit;
119         VkImageResolve          imageResolve;
120 };
121
122 struct ImageParms
123 {
124         VkImageType             imageType;
125         VkFormat                format;
126         VkExtent3D              extent;
127         VkImageLayout   operationLayout;
128 };
129
130 struct TestParams
131 {
132         union Data
133         {
134                 struct Buffer
135                 {
136                         VkDeviceSize    size;
137                 } buffer;
138
139                 ImageParms      image;
140         } src, dst;
141
142         std::vector<CopyRegion> regions;
143
144         union
145         {
146                 VkFilter                                filter;
147                 VkSampleCountFlagBits   samples;
148         };
149
150         AllocationKind allocationKind;
151 };
152
153 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&        vki,
154                                                                                 const DeviceInterface&          vkd,
155                                                                                 const VkPhysicalDevice&         physDevice,
156                                                                                 const VkDevice                          device,
157                                                                                 const VkBuffer&                         buffer,
158                                                                                 const MemoryRequirement         requirement,
159                                                                                 Allocator&                                      allocator,
160                                                                                 AllocationKind                          allocationKind)
161 {
162         switch (allocationKind)
163         {
164                 case ALLOCATION_KIND_SUBALLOCATED:
165                 {
166                         const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
167
168                         return allocator.allocate(memoryRequirements, requirement);
169                 }
170
171                 case ALLOCATION_KIND_DEDICATED:
172                 {
173                         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
174                 }
175
176                 default:
177                 {
178                         TCU_THROW(InternalError, "Invalid allocation kind");
179                 }
180         }
181 }
182
183 de::MovePtr<Allocation> allocateImage (const InstanceInterface&         vki,
184                                                                            const DeviceInterface&               vkd,
185                                                                            const VkPhysicalDevice&              physDevice,
186                                                                            const VkDevice                               device,
187                                                                            const VkImage&                               image,
188                                                                            const MemoryRequirement              requirement,
189                                                                            Allocator&                                   allocator,
190                                                                            AllocationKind                               allocationKind)
191 {
192         switch (allocationKind)
193         {
194                 case ALLOCATION_KIND_SUBALLOCATED:
195                 {
196                         const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
197
198                         return allocator.allocate(memoryRequirements, requirement);
199                 }
200
201                 case ALLOCATION_KIND_DEDICATED:
202                 {
203                         return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
204                 }
205
206                 default:
207                 {
208                         TCU_THROW(InternalError, "Invalid allocation kind");
209                 }
210         }
211 }
212
213
214 inline deUint32 getArraySize(const ImageParms& parms)
215 {
216         return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
217 }
218
219 inline VkExtent3D getExtent3D(const ImageParms& parms)
220 {
221         const VkExtent3D                extent                                  =
222         {
223                 parms.extent.width,
224                 parms.extent.height,
225                 (parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
226         };
227         return extent;
228 }
229
230 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
231 {
232         tcu::TextureFormat format;
233         switch (combinedFormat.type)
234         {
235                 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
236                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
237                         break;
238                 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
239                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
240                         break;
241                 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
242                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
243                         break;
244                 default:
245                         DE_ASSERT(false);
246                         break;
247         }
248         return format;
249 }
250
251 class CopiesAndBlittingTestInstance : public vkt::TestInstance
252 {
253 public:
254                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
255                                                                                                                                                          TestParams     testParams);
256         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
257
258         enum FillMode
259         {
260                 FILL_MODE_GRADIENT = 0,
261                 FILL_MODE_WHITE,
262                 FILL_MODE_RED,
263                 FILL_MODE_MULTISAMPLE,
264
265                 FILL_MODE_LAST
266         };
267
268 protected:
269         const TestParams                                        m_params;
270
271         Move<VkCommandPool>                                     m_cmdPool;
272         Move<VkCommandBuffer>                           m_cmdBuffer;
273         Move<VkFence>                                           m_fence;
274         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
275         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
276         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel;
277
278         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
279
280         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
281         virtual void                                            generateExpectedResult                          (void);
282         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
283         void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms);
284         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
285         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
286         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
287                                                                                 {
288                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
289                                                                                 }
290
291         de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
292                                                                                                                                                          const ImageParms&                      imageParms);
293         void                                                            submitCommandsAndWait                           (const DeviceInterface&         vk,
294                                                                                                                                                         const VkDevice                          device,
295                                                                                                                                                         const VkQueue                           queue,
296                                                                                                                                                         const VkCommandBuffer&          cmdBuffer);
297
298 private:
299         void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
300                                                                                                                                                          const VkImage&                                         dst,
301                                                                                                                                                          const ImageParms&                                      parms);
302         void                                                            readImageAspect                                         (vk::VkImage                                            src,
303                                                                                                                                                          const tcu::PixelBufferAccess&          dst,
304                                                                                                                                                          const ImageParms&                                      parms);
305 };
306
307 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
308         : vkt::TestInstance     (context)
309         , m_params                      (testParams)
310 {
311         const DeviceInterface&          vk                                      = context.getDeviceInterface();
312         const VkDevice                          vkDevice                        = context.getDevice();
313         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
314
315         if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
316         {
317                 const std::string extensionName("VK_KHR_dedicated_allocation");
318
319                 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
320                         TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
321         }
322
323         // Create command pool
324         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
325
326         // Create command buffer
327         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
328
329         // Create fence
330         m_fence = createFence(vk, vkDevice);
331 }
332
333 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
334 {
335         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(buffer.getFormat().type);
336         tcu::Vec4                                               maxValue                (1.0f);
337
338         if (buffer.getFormat().order == tcu::TextureFormat::S)
339         {
340                 // Stencil-only is stored in the first component. Stencil is always 8 bits.
341                 maxValue.x() = 1 << 8;
342         }
343         else if (buffer.getFormat().order == tcu::TextureFormat::DS)
344         {
345                 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
346                 maxValue.w() = 1 << 8;
347         }
348         else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
349         {
350                 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
351                 const tcu::IVec4        bits    = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
352                 const int                       signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
353
354                 for (int i = 0; i < 4; ++i)
355                 {
356                         if (bits[i] != 0)
357                                 maxValue[i] = static_cast<float>((1 << (bits[i] - signBit)) - 1);
358                 }
359         }
360
361         if (mode == FILL_MODE_GRADIENT)
362         {
363                 tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
364                 return;
365         }
366
367         const tcu::Vec4         redColor        (maxValue.x(),  0.0,                    0.0,                    maxValue.w());
368         const tcu::Vec4         greenColor      (0.0,                   maxValue.y(),   0.0,                    maxValue.w());
369         const tcu::Vec4         blueColor       (0.0,                   0.0,                    maxValue.z(),   maxValue.w());
370         const tcu::Vec4         whiteColor      (maxValue.x(),  maxValue.y(),   maxValue.z(),   maxValue.w());
371
372         for (int z = 0; z < depth;  ++z)
373         for (int y = 0; y < height; ++y)
374         for (int x = 0; x < width;  ++x)
375         {
376                 switch (mode)
377                 {
378                         case FILL_MODE_WHITE:
379                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
380                                 {
381                                         buffer.setPixDepth(1.0f, x, y, z);
382                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
383                                                 buffer.setPixStencil(255, x, y, z);
384                                 }
385                                 else
386                                         buffer.setPixel(whiteColor, x, y, z);
387                                 break;
388
389                         case FILL_MODE_RED:
390                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
391                                 {
392                                         buffer.setPixDepth(redColor[x % 4], x, y, z);
393                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
394                                                 buffer.setPixStencil(255 * (int)redColor[y % 4], x, y, z);
395                                 }
396                                 else
397                                         buffer.setPixel(redColor, x, y, z);
398                                 break;
399
400                         case FILL_MODE_MULTISAMPLE:
401                                 buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z);
402                                 break;
403
404                         default:
405                                 break;
406                 }
407         }
408 }
409
410 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
411 {
412         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
413         const VkDevice                          vkDevice        = m_context.getDevice();
414         const deUint32                          bufferSize      = calculateSize(bufferAccess);
415
416         // Write buffer data
417         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
418         flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
419 }
420
421 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms)
422 {
423         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
424         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
425         const VkPhysicalDevice          vkPhysDevice            = m_context.getPhysicalDevice();
426         const VkDevice                          vkDevice                        = m_context.getDevice();
427         const VkQueue                           queue                           = m_context.getUniversalQueue();
428         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
429         Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
430         Move<VkBuffer>                          buffer;
431         const deUint32                          bufferSize                      = calculateSize(imageAccess);
432         de::MovePtr<Allocation>         bufferAlloc;
433         const deUint32                          arraySize                       = getArraySize(parms);
434         const VkExtent3D                        imageExtent                     = getExtent3D(parms);
435
436         // Create source buffer
437         {
438                 const VkBufferCreateInfo                        bufferParams                    =
439                 {
440                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
441                         DE_NULL,                                                                        // const void*                  pNext;
442                         0u,                                                                                     // VkBufferCreateFlags  flags;
443                         bufferSize,                                                                     // VkDeviceSize                 size;
444                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
445                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
446                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
447                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
448                 };
449
450                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
451                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
452                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
453         }
454
455         // Barriers for copying buffer to image
456         const VkBufferMemoryBarrier                             preBufferBarrier                =
457         {
458                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
459                 DE_NULL,                                                                                // const void*          pNext;
460                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
461                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
462                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
463                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
464                 *buffer,                                                                                // VkBuffer                     buffer;
465                 0u,                                                                                             // VkDeviceSize         offset;
466                 bufferSize                                                                              // VkDeviceSize         size;
467         };
468
469         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(mapVkFormat(parms.format));
470         const bool                                                              skipPreImageBarrier             = formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
471                                                                                                                                           getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT;
472         const VkImageMemoryBarrier                              preImageBarrier                 =
473         {
474                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
475                 DE_NULL,                                                                                // const void*                          pNext;
476                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
477                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
478                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
479                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
480                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
481                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
482                 image,                                                                                  // VkImage                                      image;
483                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
484                         formatAspect,   // VkImageAspectFlags   aspect;
485                         0u,                             // deUint32                             baseMipLevel;
486                         1u,                             // deUint32                             mipLevels;
487                         0u,                             // deUint32                             baseArraySlice;
488                         arraySize,              // deUint32                             arraySize;
489                 }
490         };
491
492         const VkImageMemoryBarrier                              postImageBarrier                =
493         {
494                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
495                 DE_NULL,                                                                                // const void*                          pNext;
496                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
497                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
498                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
499                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
500                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
501                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
502                 image,                                                                                  // VkImage                                      image;
503                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
504                         formatAspect,                           // VkImageAspectFlags   aspect;
505                         0u,                                                     // deUint32                             baseMipLevel;
506                         1u,                                                     // deUint32                             mipLevels;
507                         0u,                                                     // deUint32                             baseArraySlice;
508                         arraySize,                                      // deUint32                             arraySize;
509                 }
510         };
511
512         const VkBufferImageCopy         copyRegion              =
513         {
514                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
515                 (deUint32)imageAccess.getWidth(),                               // deUint32                                     bufferRowLength;
516                 (deUint32)imageAccess.getHeight(),                              // deUint32                                     bufferImageHeight;
517                 {
518                         getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
519                         0u,                                                                                             // deUint32                             mipLevel;
520                         0u,                                                                                             // deUint32                             baseArrayLayer;
521                         arraySize,                                                                              // deUint32                             layerCount;
522                 },                                                                                              // VkImageSubresourceLayers     imageSubresource;
523                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
524                 imageExtent                                                                             // VkExtent3D                           imageExtent;
525         };
526
527         // Write buffer data
528         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
529         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
530
531         // Copy buffer to image
532         const VkCommandBufferBeginInfo                  cmdBufferBeginInfo              =
533         {
534                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
535                 DE_NULL,                                                                                                // const void*                                          pNext;
536                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
537                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
538         };
539
540         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
541         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
542                                                   1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
543         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
544         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);
545         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
546
547         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
548 }
549
550 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms)
551 {
552         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
553         {
554                 if (tcu::hasDepthComponent(src.getFormat().order))
555                 {
556                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
557                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
558                         uploadImageAspect(depthTexture.getAccess(), dst, parms);
559                 }
560
561                 if (tcu::hasStencilComponent(src.getFormat().order))
562                 {
563                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
564                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
565                         uploadImageAspect(stencilTexture.getAccess(), dst, parms);
566                 }
567         }
568         else
569                 uploadImageAspect(src, dst, parms);
570 }
571
572 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
573 {
574         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel->getAccess();
575
576         if (isFloatFormat(result.getFormat()))
577         {
578                 const tcu::Vec4 threshold (0.0f);
579                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
580                         return tcu::TestStatus::fail("CopiesAndBlitting test");
581         }
582         else
583         {
584                 const tcu::UVec4 threshold (0u);
585                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
586                         return tcu::TestStatus::fail("CopiesAndBlitting test");
587         }
588
589         return tcu::TestStatus::pass("CopiesAndBlitting test");
590 }
591
592 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
593 {
594         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
595         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
596
597         m_expectedTextureLevel  = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
598         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
599
600         for (deUint32 i = 0; i < m_params.regions.size(); i++)
601                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
602 }
603
604 class CopiesAndBlittingTestCase : public vkt::TestCase
605 {
606 public:
607                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
608                                                                                                                  const std::string&                     name,
609                                                                                                                  const std::string&                     description)
610                                                                 : vkt::TestCase (testCtx, name, description)
611                                                         {}
612
613         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
614 };
615
616 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                        image,
617                                                                                                          const tcu::PixelBufferAccess&  dst,
618                                                                                                          const ImageParms&                              imageParms)
619 {
620         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
621         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
622         const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
623         const VkDevice                          device                          = m_context.getDevice();
624         const VkQueue                           queue                           = m_context.getUniversalQueue();
625         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
626
627         Move<VkBuffer>                          buffer;
628         de::MovePtr<Allocation>         bufferAlloc;
629         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
630         const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
631         const VkExtent3D                        imageExtent                     = getExtent3D(imageParms);
632
633         // Create destination buffer
634         {
635                 const VkBufferCreateInfo                        bufferParams                    =
636                 {
637                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
638                         DE_NULL,                                                                        // const void*                  pNext;
639                         0u,                                                                                     // VkBufferCreateFlags  flags;
640                         pixelDataSize,                                                          // VkDeviceSize                 size;
641                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
642                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
643                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
644                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
645                 };
646
647                 buffer          = createBuffer(vk, device, &bufferParams);
648                 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
649                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
650
651                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
652                 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
653         }
654
655         // Barriers for copying image to buffer
656         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(mapVkFormat(imageParms.format));
657         const VkImageMemoryBarrier                              imageBarrier                    =
658         {
659                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
660                 DE_NULL,                                                                        // const void*                          pNext;
661                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
662                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
663                 imageParms.operationLayout,                                     // VkImageLayout                        oldLayout;
664                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
665                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
666                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
667                 image,                                                                          // VkImage                                      image;
668                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
669                         formatAspect,                   // VkImageAspectFlags   aspectMask;
670                         0u,                                             // deUint32                             baseMipLevel;
671                         1u,                                             // deUint32                             mipLevels;
672                         0u,                                             // deUint32                             baseArraySlice;
673                         getArraySize(imageParms)// deUint32                             arraySize;
674                 }
675         };
676
677         const VkBufferMemoryBarrier                             bufferBarrier                   =
678         {
679                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
680                 DE_NULL,                                                                        // const void*          pNext;
681                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
682                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
683                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
684                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
685                 *buffer,                                                                        // VkBuffer                     buffer;
686                 0u,                                                                                     // VkDeviceSize         offset;
687                 pixelDataSize                                                           // VkDeviceSize         size;
688         };
689
690         const VkImageMemoryBarrier                              postImageBarrier                =
691         {
692                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
693                 DE_NULL,                                                                        // const void*                          pNext;
694                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
695                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
696                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        oldLayout;
697                 imageParms.operationLayout,                                     // VkImageLayout                        newLayout;
698                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
699                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
700                 image,                                                                          // VkImage                                      image;
701                 {
702                         formatAspect,                                                           // VkImageAspectFlags   aspectMask;
703                         0u,                                                                                     // deUint32                             baseMipLevel;
704                         1u,                                                                                     // deUint32                             mipLevels;
705                         0u,                                                                                     // deUint32                             baseArraySlice;
706                         getArraySize(imageParms)                                        // deUint32                             arraySize;
707                 }                                                                                       // VkImageSubresourceRange      subresourceRange;
708         };
709
710         // Copy image to buffer
711         const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
712         const VkBufferImageCopy         copyRegion              =
713         {
714                 0u,                                                                     // VkDeviceSize                         bufferOffset;
715                 (deUint32)dst.getWidth(),                       // deUint32                                     bufferRowLength;
716                 (deUint32)dst.getHeight(),                      // deUint32                                     bufferImageHeight;
717                 {
718                         aspect,                                                         // VkImageAspectFlags           aspect;
719                         0u,                                                                     // deUint32                                     mipLevel;
720                         0u,                                                                     // deUint32                                     baseArrayLayer;
721                         getArraySize(imageParms),                       // deUint32                                     layerCount;
722                 },                                                                      // VkImageSubresourceLayers     imageSubresource;
723                 { 0, 0, 0 },                                            // VkOffset3D                           imageOffset;
724                 imageExtent                                                     // VkExtent3D                           imageExtent;
725         };
726
727         const VkCommandBufferBeginInfo                  cmdBufferBeginInfo              =
728         {
729                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
730                 DE_NULL,                                                                                                // const void*                                          pNext;
731                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
732                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
733         };
734
735         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
736         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
737         vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
738         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
739         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
740
741         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
742
743         // Read buffer data
744         invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
745         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
746 }
747
748 void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
749 {
750         const VkSubmitInfo                                              submitInfo                              =
751         {
752                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
753                 DE_NULL,                                                // const void*                          pNext;
754                 0u,                                                             // deUint32                                     waitSemaphoreCount;
755                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
756                 (const VkPipelineStageFlags*)DE_NULL,
757                 1u,                                                             // deUint32                                     commandBufferCount;
758                 &cmdBuffer,                                             // const VkCommandBuffer*       pCommandBuffers;
759                 0u,                                                             // deUint32                                     signalSemaphoreCount;
760                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
761         };
762
763         VK_CHECK(vk.resetFences(device, 1, &m_fence.get()));
764         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
765         VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
766 }
767
768 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage            image,
769                                                                                                                                                  const ImageParms&      parms)
770 {
771         const tcu::TextureFormat                imageFormat     = mapVkFormat(parms.format);
772         de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width, parms.extent.height, parms.extent.depth));
773
774         if (tcu::isCombinedDepthStencilType(imageFormat.type))
775         {
776                 if (tcu::hasDepthComponent(imageFormat.order))
777                 {
778                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
779                         readImageAspect(image, depthTexture.getAccess(), parms);
780                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
781                 }
782
783                 if (tcu::hasStencilComponent(imageFormat.order))
784                 {
785                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
786                         readImageAspect(image, stencilTexture.getAccess(), parms);
787                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
788                 }
789         }
790         else
791                 readImageAspect(image, resultLevel->getAccess(), parms);
792
793         return resultLevel;
794 }
795
796 // Copy from image to image.
797
798 class CopyImageToImage : public CopiesAndBlittingTestInstance
799 {
800 public:
801                                                                                 CopyImageToImage                        (Context&       context,
802                                                                                                                                          TestParams params);
803         virtual tcu::TestStatus                         iterate                                         (void);
804
805 protected:
806         virtual tcu::TestStatus                         checkTestResult                         (tcu::ConstPixelBufferAccess result);
807
808 private:
809         Move<VkImage>                                           m_source;
810         de::MovePtr<Allocation>                         m_sourceImageAlloc;
811         Move<VkImage>                                           m_destination;
812         de::MovePtr<Allocation>                         m_destinationImageAlloc;
813
814         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
815 };
816
817 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
818         : CopiesAndBlittingTestInstance(context, params)
819 {
820         const InstanceInterface&        vki                                     = context.getInstanceInterface();
821         const DeviceInterface&          vk                                      = context.getDeviceInterface();
822         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
823         const VkDevice                          vkDevice                        = context.getDevice();
824         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
825         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
826
827         if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
828                 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
829         {
830                 if (std::find(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1") == context.getDeviceExtensions().end())
831                         TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
832         }
833
834         VkImageFormatProperties properties;
835         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
836                                                                                                                                                                 m_params.src.image.format,
837                                                                                                                                                                 m_params.src.image.imageType,
838                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
839                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
840                                                                                                                                                                 0,
841                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
842                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
843                                                                                                                                                                 m_params.dst.image.format,
844                                                                                                                                                                 m_params.dst.image.imageType,
845                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
846                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
847                                                                                                                                                                 0,
848                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
849         {
850                 TCU_THROW(NotSupportedError, "Format not supported");
851         }
852
853         // Create source image
854         {
855                 const VkImageCreateInfo sourceImageParams               =
856                 {
857                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
858                         DE_NULL,                                                                // const void*                  pNext;
859                         0u,                                                                             // VkImageCreateFlags   flags;
860                         m_params.src.image.imageType,                   // VkImageType                  imageType;
861                         m_params.src.image.format,                              // VkFormat                             format;
862                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
863                         1u,                                                                             // deUint32                             mipLevels;
864                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
865                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
866                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
867                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
868                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
869                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
870                         1u,                                                                             // deUint32                             queueFamilyCount;
871                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
872                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
873                 };
874
875                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
876                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
877                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
878         }
879
880         // Create destination image
881         {
882                 const VkImageCreateInfo destinationImageParams  =
883                 {
884                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
885                         DE_NULL,                                                                // const void*                  pNext;
886                         0u,                                                                             // VkImageCreateFlags   flags;
887                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
888                         m_params.dst.image.format,                              // VkFormat                             format;
889                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
890                         1u,                                                                             // deUint32                             mipLevels;
891                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
892                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
893                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
894                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
895                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
896                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
897                         1u,                                                                             // deUint32                             queueFamilyCount;
898                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
899                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
900                 };
901
902                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
903                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
904                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
905         }
906 }
907
908 tcu::TestStatus CopyImageToImage::iterate (void)
909 {
910         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
911         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
912         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
913                                                                                                                                                                 (int)m_params.src.image.extent.width,
914                                                                                                                                                                 (int)m_params.src.image.extent.height,
915                                                                                                                                                                 (int)m_params.src.image.extent.depth));
916         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);
917         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
918                                                                                                                                                                 (int)m_params.dst.image.extent.width,
919                                                                                                                                                                 (int)m_params.dst.image.extent.height,
920                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
921         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);
922         generateExpectedResult();
923
924         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
925         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
926
927         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
928         const VkDevice                          vkDevice                        = m_context.getDevice();
929         const VkQueue                           queue                           = m_context.getUniversalQueue();
930
931         std::vector<VkImageCopy>        imageCopies;
932         for (deUint32 i = 0; i < m_params.regions.size(); i++)
933                 imageCopies.push_back(m_params.regions[i].imageCopy);
934
935         const VkImageMemoryBarrier      imageBarriers[]         =
936         {
937                 // source image
938                 {
939                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
940                         DE_NULL,                                                                        // const void*                          pNext;
941                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
942                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
943                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
944                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
945                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
946                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
947                         m_source.get(),                                                         // VkImage                                      image;
948                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
949                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
950                                 0u,                                                             // deUint32                             baseMipLevel;
951                                 1u,                                                             // deUint32                             mipLevels;
952                                 0u,                                                             // deUint32                             baseArraySlice;
953                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
954                         }
955                 },
956                 // destination image
957                 {
958                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
959                         DE_NULL,                                                                        // const void*                          pNext;
960                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
961                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
962                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
963                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
964                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
965                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
966                         m_destination.get(),                                            // VkImage                                      image;
967                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
968                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
969                                 0u,                                                             // deUint32                             baseMipLevel;
970                                 1u,                                                             // deUint32                             mipLevels;
971                                 0u,                                                             // deUint32                             baseArraySlice;
972                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
973                         }
974                 },
975         };
976
977         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
978         {
979                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
980                 DE_NULL,                                                                                                // const void*                                          pNext;
981                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
982                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
983         };
984
985         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
986         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);
987         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());
988         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
989
990         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
991
992         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
993
994         return checkTestResult(resultTextureLevel->getAccess());
995 }
996
997 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
998 {
999         const tcu::Vec4 fThreshold (0.0f);
1000         const tcu::UVec4 uThreshold (0u);
1001
1002         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1003         {
1004                 if (tcu::hasDepthComponent(result.getFormat().order))
1005                 {
1006                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1007                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1008                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1009
1010                         if (isFloatFormat(result.getFormat()))
1011                         {
1012                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1013                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1014                         }
1015                         else
1016                         {
1017                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1018                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1019                         }
1020                 }
1021
1022                 if (tcu::hasStencilComponent(result.getFormat().order))
1023                 {
1024                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1025                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1026                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1027
1028                         if (isFloatFormat(result.getFormat()))
1029                         {
1030                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1031                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1032                         }
1033                         else
1034                         {
1035                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1036                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1037                         }
1038                 }
1039         }
1040         else
1041         {
1042                 if (isFloatFormat(result.getFormat()))
1043                 {
1044                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1045                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1046                 }
1047                 else
1048                 {
1049                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1050                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1051                 }
1052         }
1053
1054         return tcu::TestStatus::pass("CopiesAndBlitting test");
1055 }
1056
1057 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1058 {
1059         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1060         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1061         VkExtent3D      extent          = region.imageCopy.extent;
1062
1063         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1064                 dstOffset.z = srcOffset.z;
1065         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1066         {
1067                 srcOffset.z = dstOffset.z;
1068                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1069         }
1070
1071
1072         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1073         {
1074                 DE_ASSERT(src.getFormat() == dst.getFormat());
1075
1076                 // Copy depth.
1077                 if (tcu::hasDepthComponent(src.getFormat().order))
1078                 {
1079                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1080                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1081                         tcu::copy(dstSubRegion, srcSubRegion);
1082                 }
1083
1084                 // Copy stencil.
1085                 if (tcu::hasStencilComponent(src.getFormat().order))
1086                 {
1087                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1088                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1089                         tcu::copy(dstSubRegion, srcSubRegion);
1090                 }
1091         }
1092         else
1093         {
1094                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1095                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1096                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1097                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1098
1099                 tcu::copy(dstSubRegion, srcSubRegion);
1100         }
1101 }
1102
1103 class CopyImageToImageTestCase : public vkt::TestCase
1104 {
1105 public:
1106                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
1107                                                                                                                  const std::string&                             name,
1108                                                                                                                  const std::string&                             description,
1109                                                                                                                  const TestParams                               params)
1110                                                                 : vkt::TestCase (testCtx, name, description)
1111                                                                 , m_params              (params)
1112                                                         {}
1113
1114         virtual TestInstance*   createInstance                          (Context&                                               context) const
1115                                                         {
1116                                                                 return new CopyImageToImage(context, m_params);
1117                                                         }
1118 private:
1119         TestParams                              m_params;
1120 };
1121
1122 // Copy from buffer to buffer.
1123
1124 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1125 {
1126 public:
1127                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
1128         virtual tcu::TestStatus         iterate                                         (void);
1129 private:
1130         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
1131         Move<VkBuffer>                          m_source;
1132         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1133         Move<VkBuffer>                          m_destination;
1134         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1135 };
1136
1137 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1138         : CopiesAndBlittingTestInstance (context, params)
1139 {
1140         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1141         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1142         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1143         const VkDevice                          vkDevice                        = context.getDevice();
1144         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1145         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1146
1147         // Create source buffer
1148         {
1149                 const VkBufferCreateInfo        sourceBufferParams              =
1150                 {
1151                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1152                         DE_NULL,                                                                        // const void*                  pNext;
1153                         0u,                                                                                     // VkBufferCreateFlags  flags;
1154                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
1155                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1156                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1157                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1158                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1159                 };
1160
1161                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1162                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1163                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1164         }
1165
1166         // Create destination buffer
1167         {
1168                 const VkBufferCreateInfo        destinationBufferParams =
1169                 {
1170                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1171                         DE_NULL,                                                                        // const void*                  pNext;
1172                         0u,                                                                                     // VkBufferCreateFlags  flags;
1173                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
1174                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1175                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1176                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1177                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1178                 };
1179
1180                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1181                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1182                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1183         }
1184 }
1185
1186 tcu::TestStatus CopyBufferToBuffer::iterate (void)
1187 {
1188         const int srcLevelWidth         = (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
1189         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
1190         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
1191
1192         const int dstLevelWidth         = (int)(m_params.dst.buffer.size/4);
1193         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1194         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
1195
1196         generateExpectedResult();
1197
1198         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1199         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1200
1201         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1202         const VkDevice                          vkDevice        = m_context.getDevice();
1203         const VkQueue                           queue           = m_context.getUniversalQueue();
1204
1205         const VkBufferMemoryBarrier             srcBufferBarrier        =
1206         {
1207                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1208                 DE_NULL,                                                                        // const void*          pNext;
1209                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
1210                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
1211                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1212                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1213                 *m_source,                                                                      // VkBuffer                     buffer;
1214                 0u,                                                                                     // VkDeviceSize         offset;
1215                 m_params.src.buffer.size                                        // VkDeviceSize         size;
1216         };
1217
1218         const VkBufferMemoryBarrier             dstBufferBarrier        =
1219         {
1220                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1221                 DE_NULL,                                                                        // const void*          pNext;
1222                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1223                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1224                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1225                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1226                 *m_destination,                                                         // VkBuffer                     buffer;
1227                 0u,                                                                                     // VkDeviceSize         offset;
1228                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
1229         };
1230
1231         std::vector<VkBufferCopy>               bufferCopies;
1232         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1233                 bufferCopies.push_back(m_params.regions[i].bufferCopy);
1234
1235         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1236         {
1237                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1238                 DE_NULL,                                                                                                // const void*                                          pNext;
1239                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1240                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1241         };
1242
1243         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1244         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1245         vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
1246         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);
1247         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1248         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1249
1250
1251
1252         // Read buffer data
1253         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1254         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
1255         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1256
1257         return checkTestResult(resultLevel->getAccess());
1258 }
1259
1260 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1261 {
1262         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
1263                          (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
1264                          (size_t)region.bufferCopy.size);
1265 }
1266
1267 class BufferToBufferTestCase : public vkt::TestCase
1268 {
1269 public:
1270                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
1271                                                                                                          const std::string&     name,
1272                                                                                                          const std::string&     description,
1273                                                                                                          const TestParams       params)
1274                                                                 : vkt::TestCase (testCtx, name, description)
1275                                                                 , m_params              (params)
1276                                                         {}
1277
1278         virtual TestInstance*   createInstance                  (Context& context) const
1279                                                         {
1280                                                                 return new CopyBufferToBuffer(context, m_params);
1281                                                         }
1282 private:
1283         TestParams                              m_params;
1284 };
1285
1286 // Copy from image to buffer.
1287
1288 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1289 {
1290 public:
1291                                                                 CopyImageToBuffer                       (Context&       context,
1292                                                                                                                          TestParams     testParams);
1293         virtual tcu::TestStatus         iterate                                         (void);
1294 private:
1295         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1296
1297         tcu::TextureFormat                      m_textureFormat;
1298         VkDeviceSize                            m_bufferSize;
1299
1300         Move<VkImage>                           m_source;
1301         de::MovePtr<Allocation>         m_sourceImageAlloc;
1302         Move<VkBuffer>                          m_destination;
1303         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1304 };
1305
1306 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1307         : CopiesAndBlittingTestInstance(context, testParams)
1308         , m_textureFormat(mapVkFormat(testParams.src.image.format))
1309         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1310 {
1311         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1312         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1313         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1314         const VkDevice                          vkDevice                        = context.getDevice();
1315         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1316         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1317
1318         // Create source image
1319         {
1320                 const VkImageCreateInfo         sourceImageParams               =
1321                 {
1322                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1323                         DE_NULL,                                                                // const void*                  pNext;
1324                         0u,                                                                             // VkImageCreateFlags   flags;
1325                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1326                         m_params.src.image.format,                              // VkFormat                             format;
1327                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1328                         1u,                                                                             // deUint32                             mipLevels;
1329                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1330                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1331                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1332                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1333                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1334                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1335                         1u,                                                                             // deUint32                             queueFamilyCount;
1336                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1337                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1338                 };
1339
1340                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
1341                 m_sourceImageAlloc      = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1342                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1343         }
1344
1345         // Create destination buffer
1346         {
1347                 const VkBufferCreateInfo        destinationBufferParams =
1348                 {
1349                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1350                         DE_NULL,                                                                        // const void*                  pNext;
1351                         0u,                                                                                     // VkBufferCreateFlags  flags;
1352                         m_bufferSize,                                                           // VkDeviceSize                 size;
1353                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1354                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1355                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1356                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1357                 };
1358
1359                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1360                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1361                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1362         }
1363 }
1364
1365 tcu::TestStatus CopyImageToBuffer::iterate (void)
1366 {
1367         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1368                                                                                                                                                                 m_params.src.image.extent.width,
1369                                                                                                                                                                 m_params.src.image.extent.height,
1370                                                                                                                                                                 m_params.src.image.extent.depth));
1371         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1372         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1373         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1374
1375         generateExpectedResult();
1376
1377         uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
1378         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1379
1380         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1381         const VkDevice                          vkDevice        = m_context.getDevice();
1382         const VkQueue                           queue           = m_context.getUniversalQueue();
1383
1384         // Barriers for copying image to buffer
1385         const VkImageMemoryBarrier              imageBarrier            =
1386         {
1387                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1388                 DE_NULL,                                                                        // const void*                          pNext;
1389                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1390                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1391                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1392                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1393                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1394                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1395                 *m_source,                                                                      // VkImage                                      image;
1396                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1397                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
1398                         0u,                                                             // deUint32                             baseMipLevel;
1399                         1u,                                                             // deUint32                             mipLevels;
1400                         0u,                                                             // deUint32                             baseArraySlice;
1401                         1u                                                              // deUint32                             arraySize;
1402                 }
1403         };
1404
1405         const VkBufferMemoryBarrier             bufferBarrier           =
1406         {
1407                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1408                 DE_NULL,                                                                        // const void*          pNext;
1409                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1410                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1411                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1412                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1413                 *m_destination,                                                         // VkBuffer                     buffer;
1414                 0u,                                                                                     // VkDeviceSize         offset;
1415                 m_bufferSize                                                            // VkDeviceSize         size;
1416         };
1417
1418         // Copy from image to buffer
1419         std::vector<VkBufferImageCopy>  bufferImageCopies;
1420         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1421                 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1422
1423         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1424         {
1425                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1426                 DE_NULL,                                                                                                // const void*                                          pNext;
1427                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1428                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1429         };
1430
1431         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1432         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1433         vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
1434         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1435         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1436
1437         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1438
1439         // Read buffer data
1440         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1441         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1442         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1443
1444         return checkTestResult(resultLevel->getAccess());
1445 }
1446
1447 class CopyImageToBufferTestCase : public vkt::TestCase
1448 {
1449 public:
1450                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
1451                                                                                                                  const std::string&             name,
1452                                                                                                                  const std::string&             description,
1453                                                                                                                  const TestParams               params)
1454                                                                 : vkt::TestCase (testCtx, name, description)
1455                                                                 , m_params              (params)
1456                                                         {}
1457
1458         virtual TestInstance*   createInstance                          (Context&                               context) const
1459                                                         {
1460                                                                 return new CopyImageToBuffer(context, m_params);
1461                                                         }
1462 private:
1463         TestParams                              m_params;
1464 };
1465
1466 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1467 {
1468         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
1469         if (!rowLength)
1470                 rowLength = region.bufferImageCopy.imageExtent.width;
1471
1472         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
1473         if (!imageHeight)
1474                 imageHeight = region.bufferImageCopy.imageExtent.height;
1475
1476         const int                       texelSize       = src.getFormat().getPixelSize();
1477         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1478         const VkOffset3D        srcOffset       = region.bufferImageCopy.imageOffset;
1479         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1480
1481         for (deUint32 z = 0; z < extent.depth; z++)
1482         {
1483                 for (deUint32 y = 0; y < extent.height; y++)
1484                 {
1485                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
1486                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1487                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1488                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1489                         tcu::copy(dstSubRegion, srcSubRegion);
1490                 }
1491         }
1492 }
1493
1494 // Copy from buffer to image.
1495
1496 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1497 {
1498 public:
1499                                                                 CopyBufferToImage                       (Context&       context,
1500                                                                                                                          TestParams     testParams);
1501         virtual tcu::TestStatus         iterate                                         (void);
1502 private:
1503         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1504
1505         tcu::TextureFormat                      m_textureFormat;
1506         VkDeviceSize                            m_bufferSize;
1507
1508         Move<VkBuffer>                          m_source;
1509         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1510         Move<VkImage>                           m_destination;
1511         de::MovePtr<Allocation>         m_destinationImageAlloc;
1512 };
1513
1514 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1515         : CopiesAndBlittingTestInstance(context, testParams)
1516         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1517         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1518 {
1519         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1520         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1521         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1522         const VkDevice                          vkDevice                        = context.getDevice();
1523         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1524         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1525
1526         // Create source buffer
1527         {
1528                 const VkBufferCreateInfo        sourceBufferParams              =
1529                 {
1530                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1531                         DE_NULL,                                                                        // const void*                  pNext;
1532                         0u,                                                                                     // VkBufferCreateFlags  flags;
1533                         m_bufferSize,                                                           // VkDeviceSize                 size;
1534                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1535                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1536                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1537                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1538                 };
1539
1540                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1541                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1542                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1543         }
1544
1545         // Create destination image
1546         {
1547                 const VkImageCreateInfo         destinationImageParams  =
1548                 {
1549                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1550                         DE_NULL,                                                                // const void*                  pNext;
1551                         0u,                                                                             // VkImageCreateFlags   flags;
1552                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1553                         m_params.dst.image.format,                              // VkFormat                             format;
1554                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1555                         1u,                                                                             // deUint32                             mipLevels;
1556                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1557                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1558                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1559                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1560                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1561                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1562                         1u,                                                                             // deUint32                             queueFamilyCount;
1563                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1564                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1565                 };
1566
1567                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1568                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1569                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1570         }
1571 }
1572
1573 tcu::TestStatus CopyBufferToImage::iterate (void)
1574 {
1575         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1576         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
1577         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1578                                                                                                                                                                         m_params.dst.image.extent.width,
1579                                                                                                                                                                         m_params.dst.image.extent.height,
1580                                                                                                                                                                         m_params.dst.image.extent.depth));
1581
1582         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
1583
1584         generateExpectedResult();
1585
1586         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1587         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
1588
1589         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1590         const VkDevice                          vkDevice        = m_context.getDevice();
1591         const VkQueue                           queue           = m_context.getUniversalQueue();
1592
1593         const VkImageMemoryBarrier      imageBarrier    =
1594         {
1595                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1596                 DE_NULL,                                                                        // const void*                          pNext;
1597                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1598                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1599                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1600                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
1601                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1602                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1603                 *m_destination,                                                         // VkImage                                      image;
1604                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1605                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
1606                         0u,                                                             // deUint32                             baseMipLevel;
1607                         1u,                                                             // deUint32                             mipLevels;
1608                         0u,                                                             // deUint32                             baseArraySlice;
1609                         1u                                                              // deUint32                             arraySize;
1610                 }
1611         };
1612
1613         // Copy from buffer to image
1614         std::vector<VkBufferImageCopy>          bufferImageCopies;
1615         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1616                 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1617
1618         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1619         {
1620                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1621                 DE_NULL,                                                                                                // const void*                                          pNext;
1622                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1623                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1624         };
1625
1626         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1627         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1628         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
1629         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1630
1631         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1632
1633         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
1634
1635         return checkTestResult(resultLevel->getAccess());
1636 }
1637
1638 class CopyBufferToImageTestCase : public vkt::TestCase
1639 {
1640 public:
1641                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
1642                                                                                                                  const std::string&             name,
1643                                                                                                                  const std::string&             description,
1644                                                                                                                  const TestParams               params)
1645                                                                 : vkt::TestCase (testCtx, name, description)
1646                                                                 , m_params              (params)
1647                                                         {}
1648
1649         virtual                                 ~CopyBufferToImageTestCase      (void) {}
1650
1651         virtual TestInstance*   createInstance                          (Context&                               context) const
1652                                                         {
1653                                                                 return new CopyBufferToImage(context, m_params);
1654                                                         }
1655 private:
1656         TestParams                              m_params;
1657 };
1658
1659 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1660 {
1661         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
1662         if (!rowLength)
1663                 rowLength = region.bufferImageCopy.imageExtent.width;
1664
1665         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
1666         if (!imageHeight)
1667                 imageHeight = region.bufferImageCopy.imageExtent.height;
1668
1669         const int                       texelSize       = dst.getFormat().getPixelSize();
1670         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1671         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
1672         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1673
1674         for (deUint32 z = 0; z < extent.depth; z++)
1675         {
1676                 for (deUint32 y = 0; y < extent.height; y++)
1677                 {
1678                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
1679                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1680                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1681                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1682                         tcu::copy(dstSubRegion, srcSubRegion);
1683                 }
1684         }
1685 }
1686
1687 // Copy from image to image with scaling.
1688
1689 class BlittingImages : public CopiesAndBlittingTestInstance
1690 {
1691 public:
1692                                                                                 BlittingImages                                  (Context&       context,
1693                                                                                                                                                  TestParams params);
1694         virtual tcu::TestStatus                         iterate                                                 (void);
1695 protected:
1696         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result);
1697         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1698         virtual void                                            generateExpectedResult                  (void);
1699 private:
1700         bool                                                            checkLinearFilteredResult               (const tcu::ConstPixelBufferAccess&     result,
1701                                                                                                                                                  const tcu::ConstPixelBufferAccess&     clampedReference,
1702                                                                                                                                                  const tcu::ConstPixelBufferAccess&     unclampedReference,
1703                                                                                                                                                  const tcu::TextureFormat&                      sourceFormat);
1704         bool                                                            checkNearestFilteredResult              (const tcu::ConstPixelBufferAccess&     result,
1705                                                                                                                                                  const tcu::ConstPixelBufferAccess& source);
1706
1707         Move<VkImage>                                           m_source;
1708         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1709         Move<VkImage>                                           m_destination;
1710         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1711
1712         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel;
1713 };
1714
1715 BlittingImages::BlittingImages (Context& context, TestParams params)
1716         : CopiesAndBlittingTestInstance(context, params)
1717 {
1718         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1719         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1720         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1721         const VkDevice                          vkDevice                        = context.getDevice();
1722         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1723         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1724
1725         VkImageFormatProperties properties;
1726         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1727                                                                                                                                                                 m_params.src.image.format,
1728                                                                                                                                                                 VK_IMAGE_TYPE_2D,
1729                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
1730                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1731                                                                                                                                                                 0,
1732                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1733                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1734                                                                                                                                                                 m_params.dst.image.format,
1735                                                                                                                                                                 VK_IMAGE_TYPE_2D,
1736                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
1737                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1738                                                                                                                                                                 0,
1739                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1740         {
1741                 TCU_THROW(NotSupportedError, "Format not supported");
1742         }
1743
1744         VkFormatProperties srcFormatProperties;
1745         context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
1746         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
1747         {
1748                 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
1749         }
1750
1751         VkFormatProperties dstFormatProperties;
1752         context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
1753         if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
1754         {
1755                 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
1756         }
1757
1758         if (m_params.filter == VK_FILTER_LINEAR)
1759         {
1760                 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1761                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
1762                 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1763                         TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported");
1764         }
1765
1766         // Create source image
1767         {
1768                 const VkImageCreateInfo         sourceImageParams               =
1769                 {
1770                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1771                         DE_NULL,                                                                // const void*                  pNext;
1772                         0u,                                                                             // VkImageCreateFlags   flags;
1773                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1774                         m_params.src.image.format,                              // VkFormat                             format;
1775                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1776                         1u,                                                                             // deUint32                             mipLevels;
1777                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1778                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1779                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1780                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1781                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1782                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1783                         1u,                                                                             // deUint32                             queueFamilyCount;
1784                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1785                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1786                 };
1787
1788                 m_source = createImage(vk, vkDevice, &sourceImageParams);
1789                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1790                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1791         }
1792
1793         // Create destination image
1794         {
1795                 const VkImageCreateInfo         destinationImageParams  =
1796                 {
1797                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1798                         DE_NULL,                                                                // const void*                  pNext;
1799                         0u,                                                                             // VkImageCreateFlags   flags;
1800                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1801                         m_params.dst.image.format,                              // VkFormat                             format;
1802                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1803                         1u,                                                                             // deUint32                             mipLevels;
1804                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1805                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1806                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1807                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1808                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1809                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1810                         1u,                                                                             // deUint32                             queueFamilyCount;
1811                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1812                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1813                 };
1814
1815                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1816                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1817                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1818         }
1819 }
1820
1821 tcu::TestStatus BlittingImages::iterate (void)
1822 {
1823         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
1824         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
1825         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1826                                                                                                                                                                 m_params.src.image.extent.width,
1827                                                                                                                                                                 m_params.src.image.extent.height,
1828                                                                                                                                                                 m_params.src.image.extent.depth));
1829         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1830         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1831                                                                                                                                                                          (int)m_params.dst.image.extent.width,
1832                                                                                                                                                                          (int)m_params.dst.image.extent.height,
1833                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
1834         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
1835         generateExpectedResult();
1836
1837         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1838         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1839
1840         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1841         const VkDevice                          vkDevice                        = m_context.getDevice();
1842         const VkQueue                           queue                           = m_context.getUniversalQueue();
1843
1844         std::vector<VkImageBlit>        regions;
1845         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1846                 regions.push_back(m_params.regions[i].imageBlit);
1847
1848         // Barriers for copying image to buffer
1849         const VkImageMemoryBarrier              srcImageBarrier         =
1850         {
1851                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1852                 DE_NULL,                                                                        // const void*                          pNext;
1853                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1854                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1855                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1856                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1857                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1858                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1859                 m_source.get(),                                                         // VkImage                                      image;
1860                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1861                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1862                         0u,                                                             // deUint32                             baseMipLevel;
1863                         1u,                                                             // deUint32                             mipLevels;
1864                         0u,                                                             // deUint32                             baseArraySlice;
1865                         1u                                                              // deUint32                             arraySize;
1866                 }
1867         };
1868
1869         const VkImageMemoryBarrier              dstImageBarrier         =
1870         {
1871                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1872                 DE_NULL,                                                                        // const void*                          pNext;
1873                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1874                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1875                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1876                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1877                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1878                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1879                 m_destination.get(),                                            // VkImage                                      image;
1880                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1881                         getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1882                         0u,                                                             // deUint32                             baseMipLevel;
1883                         1u,                                                             // deUint32                             mipLevels;
1884                         0u,                                                             // deUint32                             baseArraySlice;
1885                         1u                                                              // deUint32                             arraySize;
1886                 }
1887         };
1888
1889         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1890         {
1891                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1892                 DE_NULL,                                                                                                // const void*                                          pNext;
1893                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1894                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1895         };
1896
1897         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1898         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);
1899         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);
1900         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);
1901         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1902         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1903
1904         de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1905
1906         return checkTestResult(resultTextureLevel->getAccess());
1907 }
1908
1909 static float calculateFloatConversionError (int srcBits)
1910 {
1911         if (srcBits > 0)
1912         {
1913                 const int       clampedBits     = de::clamp<int>(srcBits, 0, 32);
1914                 const float     srcMaxValue     = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
1915                 const float     error           = 1.0f / srcMaxValue;
1916
1917                 return de::clamp<float>(error, 0.0f, 1.0f);
1918         }
1919         else
1920                 return 1.0f;
1921 }
1922
1923 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
1924 {
1925         tcu::Vec4 threshold(0.01f);
1926
1927         switch (format.type)
1928         {
1929         case tcu::TextureFormat::HALF_FLOAT:
1930                 threshold = tcu::Vec4(0.005f);
1931                 break;
1932
1933         case tcu::TextureFormat::FLOAT:
1934         case tcu::TextureFormat::FLOAT64:
1935                 threshold = tcu::Vec4(0.001f);
1936                 break;
1937
1938         case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
1939                 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
1940                 break;
1941
1942         case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
1943                 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
1944                 break;
1945
1946         default:
1947                 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
1948                 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
1949                                       calculateFloatConversionError(bits.y()),
1950                                       calculateFloatConversionError(bits.z()),
1951                                       calculateFloatConversionError(bits.w()));
1952         }
1953
1954         // Return value matching the channel order specified by the format
1955         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
1956                 return threshold.swizzle(2, 1, 0, 3);
1957         else
1958                 return threshold;
1959 }
1960
1961 bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess&      result,
1962                                                                                                 const tcu::ConstPixelBufferAccess&      clampedExpected,
1963                                                                                                 const tcu::ConstPixelBufferAccess&      unclampedExpected,
1964                                                                                                 const tcu::TextureFormat&                       srcFormat)
1965 {
1966         tcu::TestLog&                           log                     (m_context.getTestContext().getLog());
1967         const tcu::TextureFormat        dstFormat       = result.getFormat();
1968         bool                                            isOk            = false;
1969
1970         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
1971
1972         if (isFloatFormat(dstFormat))
1973         {
1974                 const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
1975                 const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
1976                 const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
1977                 const tcu::Vec4 threshold       = tcu::max(srcMaxDiff, dstMaxDiff);
1978
1979                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1980                 log << tcu::TestLog::EndSection;
1981
1982                 if (!isOk)
1983                 {
1984                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
1985                         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1986                         log << tcu::TestLog::EndSection;
1987                 }
1988         }
1989         else
1990         {
1991                 tcu::UVec4      threshold;
1992                 // Calculate threshold depending on channel width of destination format.
1993                 const tcu::IVec4        bitDepth        = tcu::getTextureFormatBitDepth(dstFormat);
1994                 for (deUint32 i = 0; i < 4; ++i)
1995                         threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
1996
1997                 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1998                 log << tcu::TestLog::EndSection;
1999
2000                 if (!isOk)
2001                 {
2002                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
2003                         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2004                         log << tcu::TestLog::EndSection;
2005                 }
2006         }
2007
2008         return isOk;
2009 }
2010
2011 //! Utility to encapsulate coordinate computation and loops.
2012 struct CompareEachPixelInEachRegion
2013 {
2014         virtual          ~CompareEachPixelInEachRegion  (void) {}
2015         virtual bool compare                                            (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const = 0;
2016
2017         bool forEach (const void*                                               pUserData,
2018                                   const std::vector<CopyRegion>&        regions,
2019                                   const int                                                     sourceWidth,
2020                                   const int                                                     sourceHeight,
2021                                   const tcu::PixelBufferAccess&         errorMask) const
2022         {
2023                 bool compareOk = true;
2024
2025                 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
2026                 {
2027                         const VkImageBlit& blit = regionIter->imageBlit;
2028
2029                         const int       dx              = deSign32(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
2030                         const int       dy              = deSign32(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
2031                         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);
2032                         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);
2033                         const float srcInvW     = 1.0f / static_cast<float>(sourceWidth);
2034                         const float srcInvH     = 1.0f / static_cast<float>(sourceHeight);
2035
2036                         for (int y = blit.dstOffsets[0].y; y < blit.dstOffsets[1].y; y += dy)
2037                         for (int x = blit.dstOffsets[0].x; x < blit.dstOffsets[1].x; x += dx)
2038                         {
2039                                 const tcu::Vec2 srcNormCoord
2040                                 (
2041                                         (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
2042                                         (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH
2043                                 );
2044
2045                                 if (!compare(pUserData, x, y, srcNormCoord))
2046                                 {
2047                                         errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
2048                                         compareOk = false;
2049                                 }
2050                         }
2051                 }
2052                 return compareOk;
2053         }
2054 };
2055
2056 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
2057 {
2058         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
2059         const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
2060
2061         if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
2062         {
2063                 return getFormatThreshold(format);
2064         }
2065         else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
2066                          channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
2067         {
2068                 const bool      isSigned        = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
2069                 const float     range           = isSigned ? 1.0f - (-1.0f)
2070                                                                                    : 1.0f -   0.0f;
2071
2072                 tcu::Vec4 v;
2073                 for (int i = 0; i < 4; ++i)
2074                 {
2075                         if (bitDepth[i] == 0)
2076                                 v[i] = 1.0f;
2077                         else
2078                                 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
2079                 }
2080                 return v;
2081         }
2082         else
2083         {
2084                 DE_ASSERT(0);
2085                 return tcu::Vec4();
2086         }
2087 }
2088
2089 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&        source,
2090                                                           const tcu::ConstPixelBufferAccess&    result,
2091                                                           const tcu::PixelBufferAccess&                 errorMask,
2092                                                           const std::vector<CopyRegion>&                regions)
2093 {
2094         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);
2095         tcu::LookupPrecision    precision;
2096
2097         {
2098                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
2099                 const tcu::Vec4         srcMaxDiff      = getFloatOrFixedPointFormatThreshold(source.getFormat());
2100                 const tcu::Vec4         dstMaxDiff      = getFloatOrFixedPointFormatThreshold(result.getFormat());
2101
2102                 precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
2103                 precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
2104         }
2105
2106         const struct Capture
2107         {
2108                 const tcu::ConstPixelBufferAccess&      source;
2109                 const tcu::ConstPixelBufferAccess&      result;
2110                 const tcu::Sampler&                                     sampler;
2111                 const tcu::LookupPrecision&                     precision;
2112                 const bool                                                      isSRGB;
2113         } capture =
2114         {
2115                 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
2116         };
2117
2118         const struct Loop : CompareEachPixelInEachRegion
2119         {
2120                 Loop (void) {}
2121
2122                 bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
2123                 {
2124                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
2125                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
2126                         tcu::Vec4                                               dstColor                        = c.result.getPixel(x, y);
2127
2128                         // TexLookupVerifier performs a conversion to linear space, so we have to as well
2129                         if (c.isSRGB)
2130                                 dstColor = tcu::sRGBToLinear(dstColor);
2131
2132                         return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
2133                 }
2134         } loop;
2135
2136         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
2137 }
2138
2139 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&  source,
2140                                                         const tcu::ConstPixelBufferAccess&      result,
2141                                                         const tcu::PixelBufferAccess&           errorMask,
2142                                                         const std::vector<CopyRegion>&          regions)
2143 {
2144         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);
2145         tcu::IntLookupPrecision precision;
2146
2147         {
2148                 const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
2149                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
2150
2151                 for (deUint32 i = 0; i < 4; ++i) {
2152                         precision.colorThreshold[i]     = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
2153                         precision.colorMask[i]          = dstBitDepth[i] != 0;
2154                 }
2155         }
2156
2157         // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
2158         // does the conversion on the fly without wasting memory, but this approach is more straightforward.
2159         tcu::TextureLevel                               convertedSourceTexture  (result.getFormat(), source.getWidth(), source.getHeight());
2160         const tcu::PixelBufferAccess    convertedSource                 = convertedSourceTexture.getAccess();
2161
2162         for (int y = 0; y < source.getHeight(); ++y)
2163         for (int x = 0; x < source.getWidth();  ++x)
2164                 convertedSource.setPixel(source.getPixelInt(x, y), x, y);       // will be clamped to max. representable value
2165
2166         const struct Capture
2167         {
2168                 const tcu::ConstPixelBufferAccess&      source;
2169                 const tcu::ConstPixelBufferAccess&      result;
2170                 const tcu::Sampler&                                     sampler;
2171                 const tcu::IntLookupPrecision&          precision;
2172         } capture =
2173         {
2174                 convertedSource, result, sampler, precision
2175         };
2176
2177         const struct Loop : CompareEachPixelInEachRegion
2178         {
2179                 Loop (void) {}
2180
2181                 bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const
2182                 {
2183                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
2184                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
2185                         const tcu::IVec4                                dstColor                        = c.result.getPixelInt(x, y);
2186
2187                         return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor);
2188                 }
2189         } loop;
2190
2191         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask);
2192 }
2193
2194 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
2195                                                                                                  const tcu::ConstPixelBufferAccess& source)
2196 {
2197         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
2198         const tcu::TextureFormat                dstFormat               = result.getFormat();
2199         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
2200
2201         tcu::TextureLevel               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
2202         tcu::PixelBufferAccess  errorMask                       = errorMaskStorage.getAccess();
2203         tcu::Vec4                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
2204         tcu::Vec4                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
2205         bool                                    ok                                      = false;
2206
2207         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
2208
2209         if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
2210                 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2211         {
2212                 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
2213         }
2214         else
2215                 ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);
2216
2217         if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
2218                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
2219
2220         if (!ok)
2221         {
2222                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
2223                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
2224                         << tcu::TestLog::Image("ErrorMask",     "Error mask", errorMask)
2225                         << tcu::TestLog::EndImageSet;
2226         }
2227         else
2228         {
2229                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
2230                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
2231                         << tcu::TestLog::EndImageSet;
2232         }
2233
2234         return ok;
2235 }
2236
2237 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
2238 {
2239         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
2240         const std::string failMessage("Result image is incorrect");
2241
2242         if (m_params.filter == VK_FILTER_LINEAR)
2243         {
2244                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
2245                 {
2246                         if (tcu::hasDepthComponent(result.getFormat().order))
2247                         {
2248                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
2249                                 const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
2250                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
2251                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
2252                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
2253
2254                                 if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
2255                                         return tcu::TestStatus::fail(failMessage);
2256                         }
2257
2258                         if (tcu::hasStencilComponent(result.getFormat().order))
2259                         {
2260                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
2261                                 const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
2262                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
2263                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
2264                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
2265
2266                                 if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
2267                                         return tcu::TestStatus::fail(failMessage);
2268                         }
2269                 }
2270                 else
2271                 {
2272                         const tcu::TextureFormat        sourceFormat    = mapVkFormat(m_params.src.image.format);
2273
2274                         if (!checkLinearFilteredResult(result, m_expectedTextureLevel->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
2275                                 return tcu::TestStatus::fail(failMessage);
2276                 }
2277         }
2278         else // NEAREST filtering
2279         {
2280                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
2281                 {
2282                         if (tcu::hasDepthComponent(result.getFormat().order))
2283                         {
2284                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_DEPTH;
2285                                 const tcu::ConstPixelBufferAccess               depthResult             = tcu::getEffectiveDepthStencilAccess(result, mode);
2286                                 const tcu::ConstPixelBufferAccess               depthSource             = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
2287
2288                                 if (!checkNearestFilteredResult(depthResult, depthSource))
2289                                         return tcu::TestStatus::fail(failMessage);
2290                         }
2291
2292                         if (tcu::hasStencilComponent(result.getFormat().order))
2293                         {
2294                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_STENCIL;
2295                                 const tcu::ConstPixelBufferAccess               stencilResult   = tcu::getEffectiveDepthStencilAccess(result, mode);
2296                                 const tcu::ConstPixelBufferAccess               stencilSource   = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
2297
2298                                 if (!checkNearestFilteredResult(stencilResult, stencilSource))
2299                                         return tcu::TestStatus::fail(failMessage);
2300                         }
2301                 }
2302                 else
2303                 {
2304                         if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
2305                                 return tcu::TestStatus::fail(failMessage);
2306                 }
2307         }
2308
2309         return tcu::TestStatus::pass("Pass");
2310 }
2311
2312 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
2313 {
2314         return isSRGB(format) ? linearToSRGB(color) : color;
2315 }
2316
2317 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
2318 {
2319         DE_ASSERT(filter == tcu::Sampler::LINEAR);
2320         DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
2321
2322         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
2323                                         filter, filter, 0.0f, false);
2324
2325         float sX = (float)regionExtent.x / (float)dst.getWidth();
2326         float sY = (float)regionExtent.y / (float)dst.getHeight();
2327
2328         for (int y = 0; y < dst.getHeight(); y++)
2329         for (int x = 0; x < dst.getWidth(); x++)
2330                 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);
2331 }
2332
2333 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
2334 {
2335         DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
2336
2337         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
2338                                                  filter, filter, 0.0f, false);
2339
2340         const float sX = (float)src.getWidth() / (float)dst.getWidth();
2341         const float sY = (float)src.getHeight() / (float)dst.getHeight();
2342         const float sZ = (float)src.getDepth() / (float)dst.getDepth();
2343
2344         tcu::Mat2 rotMatrix;
2345         rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
2346         rotMatrix(0,1) = 0.0f;
2347         rotMatrix(1,0) = 0.0f;
2348         rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
2349
2350         const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
2351         const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
2352
2353         if (dst.getDepth() == 1 && src.getDepth() == 1)
2354         {
2355                 for (int y = 0; y < dst.getHeight(); ++y)
2356                 for (int x = 0; x < dst.getWidth(); ++x)
2357                 {
2358                         const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2359                         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);
2360                 }
2361         }
2362         else
2363         {
2364                 for (int z = 0; z < dst.getDepth(); ++z)
2365                 for (int y = 0; y < dst.getHeight(); ++y)
2366                 for (int x = 0; x < dst.getWidth(); ++x)
2367                 {
2368                         const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2369                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z);
2370                 }
2371         }
2372 }
2373
2374 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
2375 {
2376         const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
2377         const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
2378         const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
2379         const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
2380
2381         if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
2382         {
2383                 //sourceRegion
2384                 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
2385                 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
2386
2387                 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
2388                 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
2389
2390                 //destinationRegion
2391                 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
2392                 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
2393
2394                 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
2395                 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
2396         }
2397 }
2398
2399 MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
2400 {
2401         if (x1.x >= x2.x && x1.y >= x2.y)
2402         {
2403                 return MIRROR_MODE_XY;
2404         }
2405         else if (x1.x <= x2.x && x1.y <= x2.y)
2406         {
2407                 return MIRROR_MODE_NONE;
2408         }
2409         else if (x1.x <= x2.x && x1.y >= x2.y)
2410         {
2411                 return MIRROR_MODE_Y;
2412         }
2413         else if (x1.x >= x2.x && x1.y <= x2.y)
2414         {
2415                 return MIRROR_MODE_X;
2416         }
2417         return MIRROR_MODE_LAST;
2418 }
2419
2420 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
2421 {
2422         const MirrorMode source          = getMirrorMode(s1, s2);
2423         const MirrorMode destination = getMirrorMode(d1, d2);
2424
2425         if (source == destination)
2426         {
2427                 return MIRROR_MODE_NONE;
2428         }
2429         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
2430                          (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
2431         {
2432                 return MIRROR_MODE_Y;
2433         }
2434         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
2435                          (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
2436         {
2437                 return MIRROR_MODE_X;
2438         }
2439         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
2440         {
2441                 return MIRROR_MODE_XY;
2442         }
2443         return MIRROR_MODE_LAST;
2444 }
2445
2446 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
2447 {
2448         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
2449                                                                                                 region.imageBlit.srcOffsets[1],
2450                                                                                                 region.imageBlit.dstOffsets[0],
2451                                                                                                 region.imageBlit.dstOffsets[1]);
2452
2453         flipCoordinates(region, mirrorMode);
2454
2455         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
2456         const VkOffset3D                                        srcExtent               =
2457         {
2458                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
2459                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
2460                 region.imageBlit.srcOffsets[1].z - srcOffset.z
2461         };
2462         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
2463         const VkOffset3D                                        dstExtent               =
2464         {
2465                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
2466                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
2467                 region.imageBlit.dstOffsets[1].z - dstOffset.z
2468         };
2469         const tcu::Sampler::FilterMode          filter                  = (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
2470
2471         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2472         {
2473                 DE_ASSERT(src.getFormat() == dst.getFormat());
2474                 // Scale depth.
2475                 if (tcu::hasDepthComponent(src.getFormat().order))
2476                 {
2477                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
2478                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2479                         tcu::scale(dstSubRegion, srcSubRegion, filter);
2480
2481                         if (filter == tcu::Sampler::LINEAR)
2482                         {
2483                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
2484                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2485                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
2486                         }
2487                 }
2488
2489                 // Scale stencil.
2490                 if (tcu::hasStencilComponent(src.getFormat().order))
2491                 {
2492                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
2493                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2494                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2495
2496                         if (filter == tcu::Sampler::LINEAR)
2497                         {
2498                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
2499                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2500                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
2501                         }
2502                 }
2503         }
2504         else
2505         {
2506                 const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
2507                 const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2508                 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2509
2510                 if (filter == tcu::Sampler::LINEAR)
2511                 {
2512                         const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2513                         scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter);
2514                 }
2515         }
2516 }
2517
2518 void BlittingImages::generateExpectedResult (void)
2519 {
2520         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
2521         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
2522
2523         m_expectedTextureLevel                  = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2524         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
2525
2526         if (m_params.filter == VK_FILTER_LINEAR)
2527         {
2528                 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2529                 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
2530         }
2531
2532         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2533         {
2534                 CopyRegion region = m_params.regions[i];
2535                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), region);
2536         }
2537 }
2538
2539 class BlittingTestCase : public vkt::TestCase
2540 {
2541 public:
2542                                                         BlittingTestCase                (tcu::TestContext&                              testCtx,
2543                                                                                                          const std::string&                             name,
2544                                                                                                          const std::string&                             description,
2545                                                                                                          const TestParams                               params)
2546                                                                 : vkt::TestCase (testCtx, name, description)
2547                                                                 , m_params              (params)
2548                                                         {}
2549
2550         virtual TestInstance*   createInstance                  (Context&                                               context) const
2551                                                         {
2552                                                                 return new BlittingImages(context, m_params);
2553                                                         }
2554 private:
2555         TestParams                              m_params;
2556 };
2557
2558 // Resolve image to image.
2559
2560 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
2561 class ResolveImageToImage : public CopiesAndBlittingTestInstance
2562 {
2563 public:
2564                                                                                                 ResolveImageToImage                     (Context&                                                       context,
2565                                                                                                                                                          TestParams                                                     params,
2566                                                                                                                                                          const ResolveImageToImageOptions       options);
2567         virtual tcu::TestStatus                                         iterate                                         (void);
2568 protected:
2569         virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result);
2570         void                                                                            copyMSImageToMSImage            (void);
2571 private:
2572         Move<VkImage>                                                           m_multisampledImage;
2573         de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
2574
2575         Move<VkImage>                                                           m_destination;
2576         de::MovePtr<Allocation>                                         m_destinationImageAlloc;
2577
2578         Move<VkImage>                                                           m_multisampledCopyImage;
2579         de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
2580
2581         const ResolveImageToImageOptions                        m_options;
2582
2583         virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
2584                                                                                                                                                          tcu::PixelBufferAccess                 dst,
2585                                                                                                                                                          CopyRegion                                             region);
2586 };
2587
2588 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
2589         : CopiesAndBlittingTestInstance (context, params)
2590         , m_options                                             (options)
2591 {
2592         const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
2593
2594         if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
2595                 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2596
2597         const InstanceInterface&        vki                                             = context.getInstanceInterface();
2598         const DeviceInterface&          vk                                              = context.getDeviceInterface();
2599         const VkPhysicalDevice          vkPhysDevice                    = context.getPhysicalDevice();
2600         const VkDevice                          vkDevice                                = context.getDevice();
2601         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2602         Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
2603
2604         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2605         Move<VkRenderPass>                      renderPass;
2606
2607         Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2608         Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2609         std::vector<tcu::Vec4>          vertices;
2610
2611         Move<VkBuffer>                          vertexBuffer;
2612         de::MovePtr<Allocation>         vertexBufferAlloc;
2613
2614         Move<VkPipelineLayout>          pipelineLayout;
2615         Move<VkPipeline>                        graphicsPipeline;
2616
2617         VkImageFormatProperties properties;
2618         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2619                                                                                                                                                                 m_params.src.image.format,
2620                                                                                                                                                                 m_params.src.image.imageType,
2621                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
2622                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2623                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2624                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2625                                                                                                                                                                 m_params.dst.image.format,
2626                                                                                                                                                                 m_params.dst.image.imageType,
2627                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
2628                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
2629                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2630         {
2631                 TCU_THROW(NotSupportedError, "Format not supported");
2632         }
2633
2634         // Create color image.
2635         {
2636                 VkImageCreateInfo       colorImageParams        =
2637                 {
2638                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
2639                         DE_NULL,                                                                                                                                // const void*                          pNext;
2640                         0u,                                                                                                                                             // VkImageCreateFlags           flags;
2641                         m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
2642                         m_params.src.image.format,                                                                                              // VkFormat                                     format;
2643                         getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
2644                         1u,                                                                                                                                             // deUint32                                     mipLevels;
2645                         getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
2646                         rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
2647                         VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
2648                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
2649                         VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
2650                         1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
2651                         &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
2652                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
2653                 };
2654
2655                 m_multisampledImage                                             = createImage(vk, vkDevice, &colorImageParams);
2656
2657                 // Allocate and bind color image memory.
2658                 m_multisampledImageAlloc                                = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2659                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
2660
2661                 switch (m_options)
2662                 {
2663                         case COPY_MS_IMAGE_TO_MS_IMAGE:
2664                         {
2665                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2666                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
2667                                 // Allocate and bind color image memory.
2668                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2669                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2670                                 break;
2671                         }
2672
2673                         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
2674                         {
2675                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2676                                 colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
2677                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
2678                                 // Allocate and bind color image memory.
2679                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2680                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2681                                 break;
2682                         }
2683
2684                         default :
2685                                 break;
2686                 }
2687         }
2688
2689         // Create destination image.
2690         {
2691                 const VkImageCreateInfo destinationImageParams  =
2692                 {
2693                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2694                         DE_NULL,                                                                // const void*                  pNext;
2695                         0u,                                                                             // VkImageCreateFlags   flags;
2696                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2697                         m_params.dst.image.format,                              // VkFormat                             format;
2698                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2699                         1u,                                                                             // deUint32                             mipLevels;
2700                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2701                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2702                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2703                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2704                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2705                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2706                         1u,                                                                             // deUint32                             queueFamilyCount;
2707                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2708                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2709                 };
2710
2711                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
2712                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2713                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2714         }
2715
2716         // Barriers for copying image to buffer
2717         VkImageMemoryBarrier            srcImageBarrier         =
2718         {
2719                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2720                 DE_NULL,                                                                        // const void*                          pNext;
2721                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
2722                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
2723                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
2724                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
2725                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2726                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2727                 m_multisampledImage.get(),                                      // VkImage                                      image;
2728                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2729                         VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
2730                         0u,                                                                     // deUint32                             baseMipLevel;
2731                         1u,                                                                     // deUint32                             mipLevels;
2732                         0u,                                                                     // deUint32                             baseArraySlice;
2733                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
2734                 }
2735         };
2736
2737                 // Create render pass.
2738         {
2739                 const VkAttachmentDescription   attachmentDescriptions[1]       =
2740                 {
2741                         {
2742                                 0u,                                                                                     // VkAttachmentDescriptionFlags         flags;
2743                                 m_params.src.image.format,                                      // VkFormat                                                     format;
2744                                 rasterizationSamples,                                           // VkSampleCountFlagBits                        samples;
2745                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
2746                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
2747                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
2748                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
2749                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
2750                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
2751                         },
2752                 };
2753
2754                 const VkAttachmentReference             colorAttachmentReference        =
2755                 {
2756                         0u,                                                                                                     // deUint32                     attachment;
2757                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2758                 };
2759
2760                 const VkSubpassDescription              subpassDescription                      =
2761                 {
2762                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
2763                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
2764                         0u,                                                                     // deUint32                                             inputAttachmentCount;
2765                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
2766                         1u,                                                                     // deUint32                                             colorAttachmentCount;
2767                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
2768                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
2769                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
2770                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
2771                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
2772                 };
2773
2774                 const VkRenderPassCreateInfo    renderPassParams                        =
2775                 {
2776                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
2777                         DE_NULL,                                                                        // const void*                                          pNext;
2778                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
2779                         1u,                                                                                     // deUint32                                                     attachmentCount;
2780                         attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments;
2781                         1u,                                                                                     // deUint32                                                     subpassCount;
2782                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
2783                         0u,                                                                                     // deUint32                                                     dependencyCount;
2784                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
2785                 };
2786
2787                 renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
2788         }
2789
2790         // Create pipeline layout
2791         {
2792                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
2793                 {
2794                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
2795                         DE_NULL,                                                                                        // const void*                                          pNext;
2796                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
2797                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
2798                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
2799                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
2800                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
2801                 };
2802
2803                 pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2804         }
2805
2806         // Create upper half triangle.
2807         {
2808                 const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
2809                 const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
2810                 const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
2811                 // Add triangle.
2812                 vertices.push_back(a);
2813                 vertices.push_back(c);
2814                 vertices.push_back(b);
2815         }
2816
2817         // Create vertex buffer.
2818         {
2819                 const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
2820                 const VkBufferCreateInfo        vertexBufferParams      =
2821                 {
2822                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2823                         DE_NULL,                                                                        // const void*                  pNext;
2824                         0u,                                                                                     // VkBufferCreateFlags  flags;
2825                         vertexDataSize,                                                         // VkDeviceSize                 size;
2826                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
2827                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2828                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2829                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
2830                 };
2831
2832                 vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
2833                 vertexBufferAlloc       = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2834                 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
2835
2836                 // Load vertices into vertex buffer.
2837                 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
2838                 flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize);
2839         }
2840
2841         {
2842                 Move<VkFramebuffer>             framebuffer;
2843                 Move<VkImageView>               sourceAttachmentView;
2844
2845                 // Create color attachment view.
2846                 {
2847                         const VkImageViewCreateInfo     colorAttachmentViewParams       =
2848                         {
2849                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
2850                                 DE_NULL,                                                                                                // const void*                          pNext;
2851                                 0u,                                                                                                             // VkImageViewCreateFlags       flags;
2852                                 *m_multisampledImage,                                                                   // VkImage                                      image;
2853                                 VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
2854                                 m_params.src.image.format,                                                              // VkFormat                                     format;
2855                                 componentMappingRGBA,                                                                   // VkComponentMapping           components;
2856                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
2857                         };
2858                         sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2859                 }
2860
2861                 // Create framebuffer
2862                 {
2863                         const VkImageView                               attachments[1]          =
2864                         {
2865                                         *sourceAttachmentView,
2866                         };
2867
2868                         const VkFramebufferCreateInfo   framebufferParams       =
2869                         {
2870                                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
2871                                         DE_NULL,                                                                                        // const void*                                  pNext;
2872                                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
2873                                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
2874                                         1u,                                                                                                     // deUint32                                             attachmentCount;
2875                                         attachments,                                                                            // const VkImageView*                   pAttachments;
2876                                         m_params.src.image.extent.width,                                        // deUint32                                             width;
2877                                         m_params.src.image.extent.height,                                       // deUint32                                             height;
2878                                         1u                                                                                                      // deUint32                                             layers;
2879                         };
2880
2881                         framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
2882                 }
2883
2884                 // Create pipeline
2885                 {
2886                         const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]                            =
2887                         {
2888                                 {
2889                                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2890                                         DE_NULL,                                                                                                        // const void*                                                  pNext;
2891                                         0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
2892                                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
2893                                         *vertexShaderModule,                                                                            // VkShaderModule                                               module;
2894                                         "main",                                                                                                         // const char*                                                  pName;
2895                                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2896                                 },
2897                                 {
2898                                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2899                                         DE_NULL,                                                                                                        // const void*                                                  pNext;
2900                                         0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
2901                                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
2902                                         *fragmentShaderModule,                                                                          // VkShaderModule                                               module;
2903                                         "main",                                                                                                         // const char*                                                  pName;
2904                                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2905                                 }
2906                         };
2907
2908                         const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
2909                         {
2910                                         0u,                                                                     // deUint32                             binding;
2911                                         sizeof(tcu::Vec4),                                      // deUint32                             stride;
2912                                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
2913                         };
2914
2915                         const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[1]     =
2916                         {
2917                                 {
2918                                         0u,                                                                     // deUint32     location;
2919                                         0u,                                                                     // deUint32     binding;
2920                                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
2921                                         0u                                                                      // deUint32     offset;
2922                                 }
2923                         };
2924
2925                         const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                          =
2926                         {
2927                                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
2928                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
2929                                 0u,                                                                                                                     // VkPipelineVertexInputStateCreateFlags        flags;
2930                                 1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
2931                                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2932                                 1u,                                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount;
2933                                 vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
2934                         };
2935
2936                         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                        =
2937                         {
2938                                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
2939                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2940                                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
2941                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
2942                                 false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
2943                         };
2944
2945                         const VkViewport        viewport        =
2946                         {
2947                                 0.0f,                                                                   // float        x;
2948                                 0.0f,                                                                   // float        y;
2949                                 (float)m_params.src.image.extent.width, // float        width;
2950                                 (float)m_params.src.image.extent.height,// float        height;
2951                                 0.0f,                                                                   // float        minDepth;
2952                                 1.0f                                                                    // float        maxDepth;
2953                         };
2954
2955                         const VkRect2D          scissor         =
2956                         {
2957                                 { 0, 0 },                                                                                                                               // VkOffset2D   offset;
2958                                 { m_params.src.image.extent.width, m_params.src.image.extent.height }   // VkExtent2D   extent;
2959                         };
2960
2961                         const VkPipelineViewportStateCreateInfo                 viewportStateParams             =
2962                         {
2963                                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
2964                                 DE_NULL,                                                                                                // const void*                                                  pNext;
2965                                 0u,                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
2966                                 1u,                                                                                                             // deUint32                                                             viewportCount;
2967                                 &viewport,                                                                                              // const VkViewport*                                    pViewports;
2968                                 1u,                                                                                                             // deUint32                                                             scissorCount;
2969                                 &scissor                                                                                                // const VkRect2D*                                              pScissors;
2970                         };
2971
2972                         const VkPipelineRasterizationStateCreateInfo    rasterStateParams               =
2973                         {
2974                                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
2975                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
2976                                 0u,                                                                                                                     // VkPipelineRasterizationStateCreateFlags      flags;
2977                                 false,                                                                                                          // VkBool32                                                                     depthClampEnable;
2978                                 false,                                                                                                          // VkBool32                                                                     rasterizerDiscardEnable;
2979                                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
2980                                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
2981                                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
2982                                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
2983                                 0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
2984                                 0.0f,                                                                                                           // float                                                                        depthBiasClamp;
2985                                 0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
2986                                 1.0f                                                                                                            // float                                                                        lineWidth;
2987                         };
2988
2989                         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
2990                         {
2991                                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
2992                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
2993                                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
2994                                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
2995                                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
2996                                 0.0f,                                                                                                           // float                                                                        minSampleShading;
2997                                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
2998                                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
2999                                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
3000                         };
3001
3002                         const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState       =
3003                         {
3004                                 false,                                                  // VkBool32                     blendEnable;
3005                                 VK_BLEND_FACTOR_ONE,                    // VkBlend                      srcBlendColor;
3006                                 VK_BLEND_FACTOR_ZERO,                   // VkBlend                      destBlendColor;
3007                                 VK_BLEND_OP_ADD,                                // VkBlendOp            blendOpColor;
3008                                 VK_BLEND_FACTOR_ONE,                    // VkBlend                      srcBlendAlpha;
3009                                 VK_BLEND_FACTOR_ZERO,                   // VkBlend                      destBlendAlpha;
3010                                 VK_BLEND_OP_ADD,                                // VkBlendOp            blendOpAlpha;
3011                                 (VK_COLOR_COMPONENT_R_BIT |
3012                                 VK_COLOR_COMPONENT_G_BIT |
3013                                 VK_COLOR_COMPONENT_B_BIT |
3014                                 VK_COLOR_COMPONENT_A_BIT)               // VkChannelFlags       channelWriteMask;
3015                         };
3016
3017                         const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams   =
3018                         {
3019                                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
3020                                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
3021                                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
3022                                 false,                                                                                                          // VkBool32                                                                             logicOpEnable;
3023                                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
3024                                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
3025                                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
3026                                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
3027                         };
3028
3029                         const VkGraphicsPipelineCreateInfo                      graphicsPipelineParams  =
3030                         {
3031                                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
3032                                 DE_NULL,                                                                                        // const void*                                                                          pNext;
3033                                 0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
3034                                 2u,                                                                                                     // deUint32                                                                                     stageCount;
3035                                 shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
3036                                 &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
3037                                 &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
3038                                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
3039                                 &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
3040                                 &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
3041                                 &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
3042                                 DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
3043                                 &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
3044                                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
3045                                 *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
3046                                 *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
3047                                 0u,                                                                                                     // deUint32                                                                                     subpass;
3048                                 0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
3049                                 0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
3050                         };
3051
3052                         graphicsPipeline        = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
3053                 }
3054
3055                 // Create command buffer
3056                 {
3057                         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
3058                         {
3059                                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
3060                                 DE_NULL,                                                                                // const void*                                          pNext;
3061                                 0u,                                                                                             // VkCommandBufferUsageFlags            flags;
3062                                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3063                         };
3064
3065                         const VkClearValue clearValues[1] =
3066                         {
3067                                 makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
3068                         };
3069
3070                         const VkRenderPassBeginInfo renderPassBeginInfo =
3071                         {
3072                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
3073                                 DE_NULL,                                                                                                // const void*                  pNext;
3074                                 *renderPass,                                                                                    // VkRenderPass                 renderPass;
3075                                 *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
3076                                 {
3077                                         { 0, 0 },
3078                                         { m_params.src.image.extent.width, m_params.src.image.extent.height }
3079                                 },                                                                                                              // VkRect2D                             renderArea;
3080                                 1u,                                                                                                             // deUint32                             clearValueCount;
3081                                 clearValues                                                                                             // const VkClearValue*  pClearValues;
3082                         };
3083
3084                         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
3085                         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);
3086                         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3087
3088                         const VkDeviceSize      vertexBufferOffset      = 0u;
3089
3090                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
3091                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
3092                         vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
3093
3094                         vk.cmdEndRenderPass(*m_cmdBuffer);
3095                         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
3096                 }
3097
3098                 // Queue submit.
3099                 {
3100                         const VkQueue   queue   = m_context.getUniversalQueue();
3101                         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
3102                 }
3103         }
3104 }
3105
3106 tcu::TestStatus ResolveImageToImage::iterate (void)
3107 {
3108         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
3109         const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
3110
3111         // upload the destination image
3112                 m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
3113                                                                                                                                                                 (int)m_params.dst.image.extent.width,
3114                                                                                                                                                                 (int)m_params.dst.image.extent.height,
3115                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
3116                 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
3117                 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
3118
3119                 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
3120                                                                                                                                                 (int)m_params.src.image.extent.width,
3121                                                                                                                                                 (int)m_params.src.image.extent.height,
3122                                                                                                                                                 (int)m_params.dst.image.extent.depth));
3123
3124                 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);
3125                 generateExpectedResult();
3126
3127         switch (m_options)
3128         {
3129                 case COPY_MS_IMAGE_TO_MS_IMAGE:
3130                 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
3131                         copyMSImageToMSImage();
3132                         break;
3133                 default:
3134                         break;
3135         }
3136
3137         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
3138         const VkDevice                                  vkDevice                        = m_context.getDevice();
3139         const VkQueue                                   queue                           = m_context.getUniversalQueue();
3140
3141         std::vector<VkImageResolve>             imageResolves;
3142         for (deUint32 i = 0; i < m_params.regions.size(); i++)
3143                 imageResolves.push_back(m_params.regions[i].imageResolve);
3144
3145         const VkImageMemoryBarrier      imageBarriers[]         =
3146         {
3147                 // source image
3148                 {
3149                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3150                         DE_NULL,                                                                        // const void*                          pNext;
3151                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
3152                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3153                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
3154                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
3155                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3156                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3157                         m_multisampledImage.get(),                                      // VkImage                                      image;
3158                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3159                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
3160                                 0u,                                                                     // deUint32                             baseMipLevel;
3161                                 1u,                                                                     // deUint32                             mipLevels;
3162                                 0u,                                                                     // deUint32                             baseArraySlice;
3163                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3164                         }
3165                 },
3166                 // destination image
3167                 {
3168                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3169                         DE_NULL,                                                                        // const void*                          pNext;
3170                         0u,                                                                                     // VkAccessFlags                        srcAccessMask;
3171                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3172                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3173                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
3174                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3175                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3176                         m_destination.get(),                                            // VkImage                                      image;
3177                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3178                                 getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
3179                                 0u,                                                                     // deUint32                             baseMipLevel;
3180                                 1u,                                                                     // deUint32                             mipLevels;
3181                                 0u,                                                                     // deUint32                             baseArraySlice;
3182                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3183                         }
3184                 },
3185         };
3186
3187         const VkImageMemoryBarrier postImageBarrier =
3188         {
3189                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
3190                 DE_NULL,                                                                // const void*                          pNext;
3191                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask;
3192                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
3193                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        oldLayout;
3194                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
3195                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
3196                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
3197                 m_destination.get(),                                    // VkImage                                      image;
3198                 {                                                                               // VkImageSubresourceRange      subresourceRange;
3199                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags           aspectMask;
3200                         0u,                                                                     // deUint32                                     baseMipLevel;
3201                         1u,                                                                     // deUint32                                     mipLevels;
3202                         0u,                                                                     // deUint32                                     baseArraySlice;
3203                         getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
3204                 }
3205         };
3206
3207         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
3208         {
3209                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
3210                 DE_NULL,                                                                                                // const void*                                          pNext;
3211                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
3212                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3213         };
3214
3215         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
3216         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
3217         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());
3218         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);
3219         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
3220         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3221
3222         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
3223
3224         return checkTestResult(resultTextureLevel->getAccess());
3225 }
3226
3227 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
3228 {
3229         const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel->getAccess();
3230         const float                                                     fuzzyThreshold  = 0.01f;
3231
3232         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
3233         {
3234                 const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
3235                 const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
3236                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
3237                         return tcu::TestStatus::fail("CopiesAndBlitting test");
3238         }
3239
3240         return tcu::TestStatus::pass("CopiesAndBlitting test");
3241 }
3242
3243 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
3244 {
3245         VkOffset3D srcOffset    = region.imageResolve.srcOffset;
3246                         srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
3247         VkOffset3D dstOffset    = region.imageResolve.dstOffset;
3248                         dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
3249         VkExtent3D extent               = region.imageResolve.extent;
3250
3251         const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
3252         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
3253         const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
3254         const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
3255
3256         tcu::copy(dstSubRegion, srcSubRegion);
3257 }
3258
3259 void ResolveImageToImage::copyMSImageToMSImage (void)
3260 {
3261         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
3262         const VkDevice                                  vkDevice                        = m_context.getDevice();
3263         const VkQueue                                   queue                           = m_context.getUniversalQueue();
3264         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
3265         std::vector<VkImageCopy>                imageCopies;
3266
3267         for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx)
3268         {
3269                 const VkImageSubresourceLayers  sourceSubresourceLayers =
3270                 {
3271                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
3272                         0u,                                                             // uint32_t                             mipLevel;
3273                         0u,                                                             // uint32_t                             baseArrayLayer;
3274                         1u                                                              // uint32_t                             layerCount;
3275                 };
3276
3277                 const VkImageSubresourceLayers  destinationSubresourceLayers    =
3278                 {
3279                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
3280                         0u,                                                             // uint32_t                             mipLevel;
3281                         layerNdx,                                               // uint32_t                             baseArrayLayer;
3282                         1u                                                              // uint32_t                             layerCount;
3283                 };
3284
3285                 const VkImageCopy                               imageCopy       =
3286                 {
3287                         sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
3288                         {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
3289                         destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
3290                         {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
3291                          getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
3292                 };
3293                 imageCopies.push_back(imageCopy);
3294         }
3295
3296         const VkImageMemoryBarrier              imageBarriers[]         =
3297         {
3298                 //// source image
3299                 {
3300                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3301                         DE_NULL,                                                                        // const void*                          pNext;
3302                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
3303                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3304                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
3305                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
3306                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3307                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3308                         m_multisampledImage.get(),                                      // VkImage                                      image;
3309                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3310                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
3311                                 0u,                                                                     // deUint32                             baseMipLevel;
3312                                 1u,                                                                     // deUint32                             mipLevels;
3313                                 0u,                                                                     // deUint32                             baseArraySlice;
3314                                 getArraySize(m_params.src.image)        // deUint32                             arraySize;
3315                         }
3316                 },
3317                 // destination image
3318                 {
3319                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3320                         DE_NULL,                                                                        // const void*                          pNext;
3321                         0,                                                                                      // VkAccessFlags                        srcAccessMask;
3322                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3323                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
3324                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
3325                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3326                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3327                         m_multisampledCopyImage.get(),                          // VkImage                                      image;
3328                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3329                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
3330                                 0u,                                                                     // deUint32                             baseMipLevel;
3331                                 1u,                                                                     // deUint32                             mipLevels;
3332                                 0u,                                                                     // deUint32                             baseArraySlice;
3333                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3334                         }
3335                 },
3336         };
3337
3338         const VkImageMemoryBarrier      postImageBarriers               =
3339         // source image
3340         {
3341                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3342                 DE_NULL,                                                                        // const void*                          pNext;
3343                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3344                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
3345                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3346                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
3347                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3348                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3349                 m_multisampledCopyImage.get(),                          // VkImage                                      image;
3350                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3351                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
3352                         0u,                                                                     // deUint32                             baseMipLevel;
3353                         1u,                                                                     // deUint32                             mipLevels;
3354                         0u,                                                                     // deUint32                             baseArraySlice;
3355                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3356                 }
3357         };
3358
3359         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
3360         {
3361                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
3362                 DE_NULL,                                                                                                // const void*                                          pNext;
3363                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
3364                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3365         };
3366
3367         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
3368         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);
3369         vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data());
3370         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
3371         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
3372
3373         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
3374
3375         m_multisampledImage = m_multisampledCopyImage;
3376 }
3377
3378 class ResolveImageToImageTestCase : public vkt::TestCase
3379 {
3380 public:
3381                                                         ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
3382                                                                                                                  const std::string&                                     name,
3383                                                                                                                  const std::string&                                     description,
3384                                                                                                                  const TestParams                                       params,
3385                                                                                                                  const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
3386                                                                 : vkt::TestCase (testCtx, name, description)
3387                                                                 , m_params              (params)
3388                                                                 , m_options             (options)
3389                                                         {}
3390         virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
3391
3392         virtual TestInstance*   createInstance                          (Context&                               context) const
3393                                                         {
3394                                                                 return new ResolveImageToImage(context, m_params, m_options);
3395                                                         }
3396 private:
3397         TestParams                                                      m_params;
3398         const ResolveImageToImageOptions        m_options;
3399 };
3400
3401 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
3402 {
3403         programCollection.glslSources.add("vert") << glu::VertexSource(
3404                 "#version 310 es\n"
3405                 "layout (location = 0) in highp vec4 a_position;\n"
3406                 "void main()\n"
3407                 "{\n"
3408                 "       gl_Position = a_position;\n"
3409                 "}\n");
3410
3411
3412         programCollection.glslSources.add("frag") << glu::FragmentSource(
3413                 "#version 310 es\n"
3414                 "layout (location = 0) out highp vec4 o_color;\n"
3415                 "void main()\n"
3416                 "{\n"
3417                 "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3418                 "}\n");
3419 }
3420
3421 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
3422 {
3423         return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
3424 }
3425
3426 std::string getFormatCaseName (VkFormat format)
3427 {
3428         return de::toLower(de::toString(getFormatStr(format)).substr(10));
3429 }
3430
3431 std::string getImageLayoutCaseName (VkImageLayout layout)
3432 {
3433         switch (layout)
3434         {
3435                 case VK_IMAGE_LAYOUT_GENERAL:
3436                         return "general";
3437                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3438                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3439                         return "optimal";
3440                 default:
3441                         DE_ASSERT(false);
3442                         return "";
3443         }
3444 }
3445
3446 const deInt32                                   defaultSize                             = 64;
3447 const deInt32                                   defaultHalfSize                 = defaultSize / 2;
3448 const deInt32                                   defaultFourthSize               = defaultSize / 4;
3449 const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
3450 const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
3451
3452 const VkImageSubresourceLayers  defaultSourceLayer              =
3453 {
3454         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
3455         0u,                                                     // uint32_t                             mipLevel;
3456         0u,                                                     // uint32_t                             baseArrayLayer;
3457         1u,                                                     // uint32_t                             layerCount;
3458 };
3459
3460 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
3461 {
3462         tcu::TestContext& testCtx       = group->getTestContext();
3463
3464         {
3465                 TestParams      params;
3466                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
3467                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
3468                 params.src.image.extent                         = defaultExtent;
3469                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
3470                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
3471                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
3472                 params.dst.image.extent                         = defaultExtent;
3473                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
3474                 params.allocationKind                           = allocationKind;
3475
3476                 {
3477                         const VkImageCopy                               testCopy        =
3478                         {
3479                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3480                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
3481                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3482                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
3483                                 defaultExtent,          // VkExtent3D                           extent;
3484                         };
3485
3486                         CopyRegion      imageCopy;
3487                         imageCopy.imageCopy     = testCopy;
3488
3489                         params.regions.push_back(imageCopy);
3490                 }
3491
3492                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
3493         }
3494
3495         {
3496                 TestParams      params;
3497                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
3498                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
3499                 params.src.image.extent                         = defaultExtent;
3500                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
3501                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
3502                 params.dst.image.format                         = VK_FORMAT_R32_UINT;
3503                 params.dst.image.extent                         = defaultExtent;
3504                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
3505                 params.allocationKind                           = allocationKind;
3506
3507                 {
3508                         const VkImageCopy                               testCopy        =
3509                         {
3510                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3511                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
3512                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3513                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
3514                                 defaultExtent,          // VkExtent3D                           extent;
3515                         };
3516
3517                         CopyRegion      imageCopy;
3518                         imageCopy.imageCopy     = testCopy;
3519
3520                         params.regions.push_back(imageCopy);
3521                 }
3522
3523                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
3524         }
3525
3526         {
3527                 TestParams      params;
3528                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
3529                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
3530                 params.src.image.extent                         = defaultExtent;
3531                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
3532                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
3533                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
3534                 params.dst.image.extent                         = defaultExtent;
3535                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
3536                 params.allocationKind                           = allocationKind;
3537
3538                 {
3539                         const VkImageCopy                               testCopy        =
3540                         {
3541                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     srcSubresource;
3542                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3543                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     dstSubresource;
3544                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3545                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3546                         };
3547
3548                         CopyRegion      imageCopy;
3549                         imageCopy.imageCopy     = testCopy;
3550
3551                         params.regions.push_back(imageCopy);
3552                 }
3553
3554                 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
3555         }
3556
3557         {
3558                 TestParams      params;
3559                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
3560                 params.src.image.format                         = VK_FORMAT_D32_SFLOAT;
3561                 params.src.image.extent                         = defaultExtent;
3562                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
3563                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
3564                 params.dst.image.format                         = VK_FORMAT_D32_SFLOAT;
3565                 params.dst.image.extent                         = defaultExtent;
3566                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
3567                 params.allocationKind                           = allocationKind;
3568
3569                 {
3570                         const VkImageSubresourceLayers  sourceLayer =
3571                         {
3572                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
3573                                 0u,                                                     // uint32_t                             mipLevel;
3574                                 0u,                                                     // uint32_t                             baseArrayLayer;
3575                                 1u                                                      // uint32_t                             layerCount;
3576                         };
3577                         const VkImageCopy                               testCopy        =
3578                         {
3579                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
3580                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3581                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
3582                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3583                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3584                         };
3585
3586                         CopyRegion      imageCopy;
3587                         imageCopy.imageCopy     = testCopy;
3588
3589                         params.regions.push_back(imageCopy);
3590                 }
3591
3592                 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
3593         }
3594
3595         {
3596                 TestParams      params;
3597                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
3598                 params.src.image.format                         = VK_FORMAT_S8_UINT;
3599                 params.src.image.extent                         = defaultExtent;
3600                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
3601                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
3602                 params.dst.image.format                         = VK_FORMAT_S8_UINT;
3603                 params.dst.image.extent                         = defaultExtent;
3604                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
3605                 params.allocationKind                           = allocationKind;
3606
3607                 {
3608                         const VkImageSubresourceLayers  sourceLayer =
3609                         {
3610                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
3611                                 0u,                                                             // uint32_t                             mipLevel;
3612                                 0u,                                                             // uint32_t                             baseArrayLayer;
3613                                 1u                                                              // uint32_t                             layerCount;
3614                         };
3615                         const VkImageCopy                               testCopy        =
3616                         {
3617                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
3618                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3619                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
3620                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3621                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3622                         };
3623
3624                         CopyRegion      imageCopy;
3625                         imageCopy.imageCopy     = testCopy;
3626
3627                         params.regions.push_back(imageCopy);
3628                 }
3629
3630                 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
3631         }
3632 }
3633
3634 struct CopyColorTestParams
3635 {
3636         TestParams              params;
3637         const VkFormat* compatibleFormats;
3638 };
3639
3640 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
3641 {
3642         const VkImageLayout copySrcLayouts[]            =
3643         {
3644                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3645                 VK_IMAGE_LAYOUT_GENERAL
3646         };
3647         const VkImageLayout copyDstLayouts[]            =
3648         {
3649                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3650                 VK_IMAGE_LAYOUT_GENERAL
3651         };
3652
3653         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
3654         {
3655                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
3656
3657                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
3658                 {
3659                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
3660
3661                         const std::string testName      = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
3662                                                                                   getImageLayoutCaseName(params.dst.image.operationLayout);
3663                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
3664                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
3665                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
3666                 }
3667         }
3668 }
3669
3670 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams)
3671 {
3672         bool result = true;
3673
3674         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
3675         {
3676                 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
3677
3678                 result =
3679                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
3680                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
3681         }
3682
3683         return result;
3684 }
3685
3686 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
3687 {
3688         for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
3689         {
3690                 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
3691                 if (!isSupportedByFramework(testParams.params.dst.image.format))
3692                         continue;
3693
3694                 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
3695                         continue;
3696
3697                 const std::string description   = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
3698                 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
3699         }
3700 }
3701
3702 const VkFormat  compatibleFormats8Bit[]         =
3703 {
3704         VK_FORMAT_R4G4_UNORM_PACK8,
3705         VK_FORMAT_R8_UNORM,
3706         VK_FORMAT_R8_SNORM,
3707         VK_FORMAT_R8_USCALED,
3708         VK_FORMAT_R8_SSCALED,
3709         VK_FORMAT_R8_UINT,
3710         VK_FORMAT_R8_SINT,
3711         VK_FORMAT_R8_SRGB,
3712
3713         VK_FORMAT_UNDEFINED
3714 };
3715 const VkFormat  compatibleFormats16Bit[]        =
3716 {
3717         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3718         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3719         VK_FORMAT_R5G6B5_UNORM_PACK16,
3720         VK_FORMAT_B5G6R5_UNORM_PACK16,
3721         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3722         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3723         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3724         VK_FORMAT_R8G8_UNORM,
3725         VK_FORMAT_R8G8_SNORM,
3726         VK_FORMAT_R8G8_USCALED,
3727         VK_FORMAT_R8G8_SSCALED,
3728         VK_FORMAT_R8G8_UINT,
3729         VK_FORMAT_R8G8_SINT,
3730         VK_FORMAT_R8G8_SRGB,
3731         VK_FORMAT_R16_UNORM,
3732         VK_FORMAT_R16_SNORM,
3733         VK_FORMAT_R16_USCALED,
3734         VK_FORMAT_R16_SSCALED,
3735         VK_FORMAT_R16_UINT,
3736         VK_FORMAT_R16_SINT,
3737         VK_FORMAT_R16_SFLOAT,
3738
3739         VK_FORMAT_UNDEFINED
3740 };
3741 const VkFormat  compatibleFormats24Bit[]        =
3742 {
3743         VK_FORMAT_R8G8B8_UNORM,
3744         VK_FORMAT_R8G8B8_SNORM,
3745         VK_FORMAT_R8G8B8_USCALED,
3746         VK_FORMAT_R8G8B8_SSCALED,
3747         VK_FORMAT_R8G8B8_UINT,
3748         VK_FORMAT_R8G8B8_SINT,
3749         VK_FORMAT_R8G8B8_SRGB,
3750         VK_FORMAT_B8G8R8_UNORM,
3751         VK_FORMAT_B8G8R8_SNORM,
3752         VK_FORMAT_B8G8R8_USCALED,
3753         VK_FORMAT_B8G8R8_SSCALED,
3754         VK_FORMAT_B8G8R8_UINT,
3755         VK_FORMAT_B8G8R8_SINT,
3756         VK_FORMAT_B8G8R8_SRGB,
3757
3758         VK_FORMAT_UNDEFINED
3759 };
3760 const VkFormat  compatibleFormats32Bit[]        =
3761 {
3762         VK_FORMAT_R8G8B8A8_UNORM,
3763         VK_FORMAT_R8G8B8A8_SNORM,
3764         VK_FORMAT_R8G8B8A8_USCALED,
3765         VK_FORMAT_R8G8B8A8_SSCALED,
3766         VK_FORMAT_R8G8B8A8_UINT,
3767         VK_FORMAT_R8G8B8A8_SINT,
3768         VK_FORMAT_R8G8B8A8_SRGB,
3769         VK_FORMAT_B8G8R8A8_UNORM,
3770         VK_FORMAT_B8G8R8A8_SNORM,
3771         VK_FORMAT_B8G8R8A8_USCALED,
3772         VK_FORMAT_B8G8R8A8_SSCALED,
3773         VK_FORMAT_B8G8R8A8_UINT,
3774         VK_FORMAT_B8G8R8A8_SINT,
3775         VK_FORMAT_B8G8R8A8_SRGB,
3776         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3777         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3778         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
3779         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
3780         VK_FORMAT_A8B8G8R8_UINT_PACK32,
3781         VK_FORMAT_A8B8G8R8_SINT_PACK32,
3782         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3783         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3784         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
3785         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
3786         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
3787         VK_FORMAT_A2R10G10B10_UINT_PACK32,
3788         VK_FORMAT_A2R10G10B10_SINT_PACK32,
3789         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3790         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
3791         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
3792         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
3793         VK_FORMAT_A2B10G10R10_UINT_PACK32,
3794         VK_FORMAT_A2B10G10R10_SINT_PACK32,
3795         VK_FORMAT_R16G16_UNORM,
3796         VK_FORMAT_R16G16_SNORM,
3797         VK_FORMAT_R16G16_USCALED,
3798         VK_FORMAT_R16G16_SSCALED,
3799         VK_FORMAT_R16G16_UINT,
3800         VK_FORMAT_R16G16_SINT,
3801         VK_FORMAT_R16G16_SFLOAT,
3802         VK_FORMAT_R32_UINT,
3803         VK_FORMAT_R32_SINT,
3804         VK_FORMAT_R32_SFLOAT,
3805
3806         VK_FORMAT_UNDEFINED
3807 };
3808 const VkFormat  compatibleFormats48Bit[]        =
3809 {
3810         VK_FORMAT_R16G16B16_UNORM,
3811         VK_FORMAT_R16G16B16_SNORM,
3812         VK_FORMAT_R16G16B16_USCALED,
3813         VK_FORMAT_R16G16B16_SSCALED,
3814         VK_FORMAT_R16G16B16_UINT,
3815         VK_FORMAT_R16G16B16_SINT,
3816         VK_FORMAT_R16G16B16_SFLOAT,
3817
3818         VK_FORMAT_UNDEFINED
3819 };
3820 const VkFormat  compatibleFormats64Bit[]        =
3821 {
3822         VK_FORMAT_R16G16B16A16_UNORM,
3823         VK_FORMAT_R16G16B16A16_SNORM,
3824         VK_FORMAT_R16G16B16A16_USCALED,
3825         VK_FORMAT_R16G16B16A16_SSCALED,
3826         VK_FORMAT_R16G16B16A16_UINT,
3827         VK_FORMAT_R16G16B16A16_SINT,
3828         VK_FORMAT_R16G16B16A16_SFLOAT,
3829         VK_FORMAT_R32G32_UINT,
3830         VK_FORMAT_R32G32_SINT,
3831         VK_FORMAT_R32G32_SFLOAT,
3832         VK_FORMAT_R64_UINT,
3833         VK_FORMAT_R64_SINT,
3834         VK_FORMAT_R64_SFLOAT,
3835
3836         VK_FORMAT_UNDEFINED
3837 };
3838 const VkFormat  compatibleFormats96Bit[]        =
3839 {
3840         VK_FORMAT_R32G32B32_UINT,
3841         VK_FORMAT_R32G32B32_SINT,
3842         VK_FORMAT_R32G32B32_SFLOAT,
3843
3844         VK_FORMAT_UNDEFINED
3845 };
3846 const VkFormat  compatibleFormats128Bit[]       =
3847 {
3848         VK_FORMAT_R32G32B32A32_UINT,
3849         VK_FORMAT_R32G32B32A32_SINT,
3850         VK_FORMAT_R32G32B32A32_SFLOAT,
3851         VK_FORMAT_R64G64_UINT,
3852         VK_FORMAT_R64G64_SINT,
3853         VK_FORMAT_R64G64_SFLOAT,
3854
3855         VK_FORMAT_UNDEFINED
3856 };
3857 const VkFormat  compatibleFormats192Bit[]       =
3858 {
3859         VK_FORMAT_R64G64B64_UINT,
3860         VK_FORMAT_R64G64B64_SINT,
3861         VK_FORMAT_R64G64B64_SFLOAT,
3862
3863         VK_FORMAT_UNDEFINED
3864 };
3865 const VkFormat  compatibleFormats256Bit[]       =
3866 {
3867         VK_FORMAT_R64G64B64A64_UINT,
3868         VK_FORMAT_R64G64B64A64_SINT,
3869         VK_FORMAT_R64G64B64A64_SFLOAT,
3870
3871         VK_FORMAT_UNDEFINED
3872 };
3873
3874 const VkFormat* colorImageFormatsToTest[]       =
3875 {
3876         compatibleFormats8Bit,
3877         compatibleFormats16Bit,
3878         compatibleFormats24Bit,
3879         compatibleFormats32Bit,
3880         compatibleFormats48Bit,
3881         compatibleFormats64Bit,
3882         compatibleFormats96Bit,
3883         compatibleFormats128Bit,
3884         compatibleFormats192Bit,
3885         compatibleFormats256Bit,
3886 };
3887
3888 const VkFormat  dedicatedAllocationImageToImageFormatsToTest[]  =
3889 {
3890         // From compatibleFormats8Bit
3891         VK_FORMAT_R4G4_UNORM_PACK8,
3892         VK_FORMAT_R8_SRGB,
3893
3894         // From compatibleFormats16Bit
3895         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3896         VK_FORMAT_R16_SFLOAT,
3897
3898         // From compatibleFormats24Bit
3899         VK_FORMAT_R8G8B8_UNORM,
3900         VK_FORMAT_B8G8R8_SRGB,
3901
3902         // From compatibleFormats32Bit
3903         VK_FORMAT_R8G8B8A8_UNORM,
3904         VK_FORMAT_R32_SFLOAT,
3905
3906         // From compatibleFormats48Bit
3907         VK_FORMAT_R16G16B16_UNORM,
3908         VK_FORMAT_R16G16B16_SFLOAT,
3909
3910         // From compatibleFormats64Bit
3911         VK_FORMAT_R16G16B16A16_UNORM,
3912         VK_FORMAT_R64_SFLOAT,
3913
3914         // From compatibleFormats96Bit
3915         VK_FORMAT_R32G32B32_UINT,
3916         VK_FORMAT_R32G32B32_SFLOAT,
3917
3918         // From compatibleFormats128Bit
3919         VK_FORMAT_R32G32B32A32_UINT,
3920         VK_FORMAT_R64G64_SFLOAT,
3921
3922         // From compatibleFormats192Bit
3923         VK_FORMAT_R64G64B64_UINT,
3924         VK_FORMAT_R64G64B64_SFLOAT,
3925
3926         // From compatibleFormats256Bit
3927         VK_FORMAT_R64G64B64A64_UINT,
3928         VK_FORMAT_R64G64B64A64_SFLOAT,
3929 };
3930
3931 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
3932 {
3933         TestParams      params;
3934         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3935         params.src.image.extent         = defaultExtent;
3936         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3937         params.dst.image.extent         = defaultExtent;
3938         params.allocationKind           = allocationKind;
3939
3940         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
3941         {
3942                 const VkImageCopy                               testCopy =
3943                 {
3944                         defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
3945                         {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
3946                         defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
3947                         {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
3948                         {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
3949                 };
3950
3951                 CopyRegion      imageCopy;
3952                 imageCopy.imageCopy = testCopy;
3953
3954                 params.regions.push_back(imageCopy);
3955         }
3956
3957         if (allocationKind == ALLOCATION_KIND_DEDICATED)
3958         {
3959                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3960                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
3961                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
3962         }
3963
3964         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3965         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
3966         {
3967                 const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
3968                 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
3969                 {
3970                         params.src.image.format = compatibleFormats[srcFormatIndex];
3971                         if (!isSupportedByFramework(params.src.image.format))
3972                                 continue;
3973
3974                         CopyColorTestParams     testParams;
3975                         testParams.params                               = params;
3976                         testParams.compatibleFormats    = compatibleFormats;
3977
3978                         const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
3979                         addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
3980                 }
3981         }
3982 }
3983
3984 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
3985 {
3986         const VkImageLayout copySrcLayouts[]            =
3987         {
3988                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3989                 VK_IMAGE_LAYOUT_GENERAL
3990         };
3991         const VkImageLayout copyDstLayouts[]            =
3992         {
3993                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3994                 VK_IMAGE_LAYOUT_GENERAL
3995         };
3996
3997         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
3998         {
3999                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
4000                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
4001                 {
4002                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
4003
4004                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
4005                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
4006                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
4007                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
4008                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
4009                 }
4010         }
4011 }
4012
4013 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4014 {
4015         const VkFormat  depthAndStencilFormats[]        =
4016         {
4017                 VK_FORMAT_D16_UNORM,
4018                 VK_FORMAT_X8_D24_UNORM_PACK32,
4019                 VK_FORMAT_D32_SFLOAT,
4020                 VK_FORMAT_S8_UINT,
4021                 VK_FORMAT_D16_UNORM_S8_UINT,
4022                 VK_FORMAT_D24_UNORM_S8_UINT,
4023                 VK_FORMAT_D32_SFLOAT_S8_UINT,
4024         };
4025
4026         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
4027         {
4028                 TestParams      params;
4029                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4030                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4031                 params.src.image.extent                         = defaultExtent;
4032                 params.dst.image.extent                         = defaultExtent;
4033                 params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
4034                 params.dst.image.format                         = params.src.image.format;
4035                 params.allocationKind                           = allocationKind;
4036
4037                 const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
4038                 const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
4039
4040                 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
4041                 {
4042                         CopyRegion                      copyRegion;
4043                         const VkOffset3D        srcOffset       = {0, 0, 0};
4044                         const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
4045                         const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
4046
4047                         if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4048                         {
4049                                 const VkImageCopy                               testCopy        =
4050                                 {
4051                                         defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
4052                                         srcOffset,                                      // VkOffset3D                           srcOffset;
4053                                         defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
4054                                         dstOffset,                                      // VkOffset3D                           dstOffset;
4055                                         extent,                                         // VkExtent3D                           extent;
4056                                 };
4057
4058                                 copyRegion.imageCopy    = testCopy;
4059                                 params.regions.push_back(copyRegion);
4060                         }
4061                         if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4062                         {
4063                                 const VkImageCopy                               testCopy        =
4064                                 {
4065                                         defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
4066                                         srcOffset,                                      // VkOffset3D                           srcOffset;
4067                                         defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
4068                                         dstOffset,                                      // VkOffset3D                           dstOffset;
4069                                         extent,                                         // VkExtent3D                           extent;
4070                                 };
4071
4072                                 copyRegion.imageCopy    = testCopy;
4073                                 params.regions.push_back(copyRegion);
4074                         }
4075                 }
4076
4077                 const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
4078                 const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
4079                 addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
4080         }
4081 }
4082
4083 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4084 {
4085         addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind);
4086         addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind);
4087 }
4088
4089 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4090 {
4091         tcu::TestContext& testCtx       = group->getTestContext();
4092
4093         {
4094                 TestParams      params3DTo2D;
4095                 const deUint32  slicesLayers                    = 16u;
4096                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
4097                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4098                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
4099                 params3DTo2D.src.image.extent.depth             = slicesLayers;
4100                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4101                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
4102                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4103                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
4104                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
4105                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4106                 params3DTo2D.allocationKind                             = allocationKind;
4107
4108                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4109                 {
4110                         const VkImageSubresourceLayers  sourceLayer     =
4111                         {
4112                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4113                                 0u,                                                     // uint32_t                             mipLevel;
4114                                 0u,                                                     // uint32_t                             baseArrayLayer;
4115                                 1u                                                      // uint32_t                             layerCount;
4116                         };
4117
4118                         const VkImageSubresourceLayers  destinationLayer        =
4119                         {
4120                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4121                                 0u,                                                     // uint32_t                             mipLevel;
4122                                 slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
4123                                 1u                                                      // uint32_t                             layerCount;
4124                         };
4125
4126                         const VkImageCopy                               testCopy        =
4127                         {
4128                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
4129                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                                   srcOffset;
4130                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
4131                                 {0, 0, 0},                                                      // VkOffset3D                                   dstOffset;
4132                                 defaultHalfExtent,                                      // VkExtent3D                                   extent;
4133                         };
4134
4135                         CopyRegion      imageCopy;
4136                         imageCopy.imageCopy     = testCopy;
4137
4138                         params3DTo2D.regions.push_back(imageCopy);
4139                 }
4140                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
4141         }
4142
4143         {
4144                 TestParams      params2DTo3D;
4145                 const deUint32  slicesLayers                    = 16u;
4146                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
4147                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4148                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
4149                 params2DTo3D.src.image.extent.depth             = slicesLayers;
4150                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4151                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
4152                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4153                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
4154                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
4155                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4156                 params2DTo3D.allocationKind                             = allocationKind;
4157
4158                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4159                 {
4160                         const VkImageSubresourceLayers  sourceLayer     =
4161                         {
4162                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4163                                 0u,                                                     // uint32_t                             mipLevel;
4164                                 slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
4165                                 1u                                                      // uint32_t                             layerCount;
4166                         };
4167
4168                         const VkImageSubresourceLayers  destinationLayer        =
4169                         {
4170                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4171                                 0u,                                                     // uint32_t                             mipLevel;
4172                                 0u,                                                     // uint32_t                             baseArrayLayer;
4173                                 1u                                                      // uint32_t                             layerCount;
4174                         };
4175
4176                         const VkImageCopy                               testCopy        =
4177                         {
4178                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
4179                                 {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
4180                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
4181                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           dstOffset;
4182                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
4183                         };
4184
4185                         CopyRegion      imageCopy;
4186                         imageCopy.imageCopy     = testCopy;
4187
4188                         params2DTo3D.regions.push_back(imageCopy);
4189                 }
4190
4191                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
4192         }
4193
4194         {
4195                 TestParams      params3DTo2D;
4196                 const deUint32  slicesLayers                    = 16u;
4197                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
4198                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4199                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
4200                 params3DTo2D.src.image.extent.depth             = slicesLayers;
4201                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4202                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
4203                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4204                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
4205                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
4206                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4207                 params3DTo2D.allocationKind                             = allocationKind;
4208
4209                 {
4210                         const VkImageSubresourceLayers  sourceLayer     =
4211                         {
4212                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4213                                 0u,                                                     // uint32_t                             mipLevel;
4214                                 0u,                                                     // uint32_t                             baseArrayLayer;
4215                                 1u                                                      // uint32_t                             layerCount;
4216                         };
4217
4218                         const VkImageSubresourceLayers  destinationLayer        =
4219                         {
4220                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4221                                 0u,                                                     // uint32_t                             mipLevel;
4222                                 0,                                                      // uint32_t                             baseArrayLayer;
4223                                 slicesLayers                            // uint32_t                             layerCount;
4224                         };
4225
4226                         const VkImageCopy                               testCopy        =
4227                         {
4228                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
4229                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
4230                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
4231                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
4232                                 params3DTo2D.src.image.extent   // VkExtent3D                           extent;
4233                         };
4234
4235                         CopyRegion      imageCopy;
4236                         imageCopy.imageCopy     = testCopy;
4237
4238                         params3DTo2D.regions.push_back(imageCopy);
4239                 }
4240                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
4241         }
4242
4243         {
4244                 TestParams      params2DTo3D;
4245                 const deUint32  slicesLayers                    = 16u;
4246                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
4247                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4248                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
4249                 params2DTo3D.src.image.extent.depth             = slicesLayers;
4250                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4251                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
4252                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4253                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
4254                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
4255                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4256                 params2DTo3D.allocationKind                             = allocationKind;
4257
4258                 {
4259                         const VkImageSubresourceLayers  sourceLayer     =
4260                         {
4261                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4262                                 0u,                                                     // uint32_t                             mipLevel;
4263                                 0u,                                                     // uint32_t                             baseArrayLayer;
4264                                 slicesLayers                            // uint32_t                             layerCount;
4265                         };
4266
4267                         const VkImageSubresourceLayers  destinationLayer        =
4268                         {
4269                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4270                                 0u,                                                     // uint32_t                             mipLevel;
4271                                 0u,                                                     // uint32_t                             baseArrayLayer;
4272                                 1u                                                      // uint32_t                             layerCount;
4273                         };
4274
4275                         const VkImageCopy                               testCopy        =
4276                         {
4277                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
4278                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
4279                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
4280                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
4281                                 params2DTo3D.dst.image.extent,  // VkExtent3D                           extent;
4282                         };
4283
4284                         CopyRegion      imageCopy;
4285                         imageCopy.imageCopy     = testCopy;
4286
4287                         params2DTo3D.regions.push_back(imageCopy);
4288                 }
4289
4290                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
4291         }
4292
4293         {
4294                 TestParams      params3DTo2D;
4295                 const deUint32  slicesLayers                    = 16u;
4296                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
4297                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4298                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
4299                 params3DTo2D.src.image.extent.depth             = slicesLayers;
4300                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4301                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
4302                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4303                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
4304                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
4305                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4306                 params3DTo2D.allocationKind                             = allocationKind;
4307
4308                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
4309                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
4310
4311                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4312                 {
4313                         const VkImageSubresourceLayers  sourceLayer     =
4314                         {
4315                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4316                                 0u,                                                     // uint32_t                             mipLevel;
4317                                 0u,                                                     // uint32_t                             baseArrayLayer;
4318                                 1u                                                      // uint32_t                             layerCount;
4319                         };
4320
4321                         const VkImageSubresourceLayers  destinationLayer        =
4322                         {
4323                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
4324                                         0u,                                                             // uint32_t                             mipLevel;
4325                                         slicesLayersNdx,                                // uint32_t                             baseArrayLayer;
4326                                         1u                                                              // uint32_t                             layerCount;
4327                         };
4328
4329
4330                         const VkImageCopy                               testCopy        =
4331                         {
4332                                 sourceLayer,                                                                                                                    // VkImageSubresourceLayers     srcSubresource;
4333                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D                           srcOffset;
4334                                         destinationLayer,                                                                                                       // VkImageSubresourceLayers     dstSubresource;
4335                                         {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                         // VkOffset3D                           dstOffset;
4336                                         {
4337                                                 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
4338                                                 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
4339                                                 1
4340                                         }                                                                                                                                       // VkExtent3D                           extent;
4341                         };
4342
4343                         CopyRegion      imageCopy;
4344                         imageCopy.imageCopy = testCopy;
4345                         params3DTo2D.regions.push_back(imageCopy);
4346                 }
4347                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
4348         }
4349
4350         {
4351                 TestParams      params2DTo3D;
4352                 const deUint32  slicesLayers                    = 16u;
4353                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
4354                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4355                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
4356                 params2DTo3D.src.image.extent.depth             = slicesLayers;
4357                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4358                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
4359                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
4360                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
4361                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
4362                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4363                 params2DTo3D.allocationKind                             = allocationKind;
4364
4365                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
4366                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
4367
4368                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4369                 {
4370                         const VkImageSubresourceLayers  sourceLayer     =
4371                         {
4372                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4373                                 0u,                                                     // uint32_t                             mipLevel;
4374                                 slicesLayersNdx,                        // uint32_t                             baseArrayLayer;
4375                                 1u                                                      // uint32_t                             layerCount;
4376                         };
4377
4378                         const VkImageSubresourceLayers  destinationLayer        =
4379                         {
4380                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4381                                 0u,                                                     // uint32_t                             mipLevel;
4382                                 0u,                                                     // uint32_t                             baseArrayLayer;
4383                                 1u                                                      // uint32_t                             layerCount;
4384                         };
4385
4386                         const VkImageCopy                               testCopy        =
4387                         {
4388                                 sourceLayer,                                                                                                                            // VkImageSubresourceLayers     srcSubresource;
4389                                 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                                         // VkOffset3D                           srcOffset;
4390                                 destinationLayer,                                                                                                                       // VkImageSubresourceLayers     dstSubresource;
4391                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},       // VkOffset3D                           dstOffset;
4392                                 {
4393                                         defaultHalfExtent.width - regionWidth*slicesLayersNdx,
4394                                         defaultHalfExtent.height - regionHeight*slicesLayersNdx,
4395                                         1
4396                                 }                                                                                                                                                       // VkExtent3D                           extent;
4397                         };
4398
4399                         CopyRegion      imageCopy;
4400                         imageCopy.imageCopy     = testCopy;
4401
4402                         params2DTo3D.regions.push_back(imageCopy);
4403                 }
4404
4405                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
4406         }
4407 }
4408
4409 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4410 {
4411         addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind);
4412         addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind);
4413         addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind);
4414 }
4415
4416 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4417 {
4418         tcu::TestContext& testCtx       = group->getTestContext();
4419
4420         {
4421                 TestParams      params;
4422                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4423                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4424                 params.src.image.extent                         = defaultExtent;
4425                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4426                 params.dst.buffer.size                          = defaultSize * defaultSize;
4427                 params.allocationKind                           = allocationKind;
4428
4429                 const VkBufferImageCopy bufferImageCopy =
4430                 {
4431                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
4432                         0u,                                                                                     // uint32_t                                     bufferRowLength;
4433                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
4434                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
4435                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
4436                         defaultExtent                                                           // VkExtent3D                           imageExtent;
4437                 };
4438                 CopyRegion      copyRegion;
4439                 copyRegion.bufferImageCopy      = bufferImageCopy;
4440
4441                 params.regions.push_back(copyRegion);
4442
4443                 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
4444         }
4445
4446         {
4447                 TestParams      params;
4448                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4449                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4450                 params.src.image.extent                         = defaultExtent;
4451                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4452                 params.dst.buffer.size                          = defaultSize * defaultSize;
4453                 params.allocationKind                           = allocationKind;
4454
4455                 const VkBufferImageCopy bufferImageCopy =
4456                 {
4457                         defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
4458                         0u,                                                                                     // uint32_t                                     bufferRowLength;
4459                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
4460                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
4461                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
4462                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
4463                 };
4464                 CopyRegion      copyRegion;
4465                 copyRegion.bufferImageCopy      = bufferImageCopy;
4466
4467                 params.regions.push_back(copyRegion);
4468
4469                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
4470         }
4471
4472         {
4473                 TestParams      params;
4474                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4475                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4476                 params.src.image.extent                         = defaultExtent;
4477                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4478                 params.dst.buffer.size                          = defaultSize * defaultSize;
4479                 params.allocationKind                           = allocationKind;
4480
4481                 const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
4482                 const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
4483                 const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
4484                 deUint32                        divisor         = 1;
4485                 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
4486                 {
4487                         const deUint32                  bufferRowLength         = defaultFourthSize;
4488                         const deUint32                  bufferImageHeight       = defaultFourthSize;
4489                         const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
4490                         DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
4491                         DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
4492                         DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
4493
4494                         CopyRegion                              region;
4495                         const VkBufferImageCopy bufferImageCopy         =
4496                         {
4497                                 offset,                                         // VkDeviceSize                         bufferOffset;
4498                                 bufferRowLength,                        // uint32_t                                     bufferRowLength;
4499                                 bufferImageHeight,                      // uint32_t                                     bufferImageHeight;
4500                                 defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
4501                                 {0, 0, 0},                                      // VkOffset3D                           imageOffset;
4502                                 imageExtent                                     // VkExtent3D                           imageExtent;
4503                         };
4504                         region.bufferImageCopy  = bufferImageCopy;
4505                         params.regions.push_back(region);
4506                 }
4507
4508                 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
4509         }
4510 }
4511
4512 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4513 {
4514         tcu::TestContext& testCtx       = group->getTestContext();
4515
4516         {
4517                 TestParams      params;
4518                 params.src.buffer.size                          = defaultSize * defaultSize;
4519                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4520                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
4521                 params.dst.image.extent                         = defaultExtent;
4522                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4523                 params.allocationKind                           = allocationKind;
4524
4525                 const VkBufferImageCopy bufferImageCopy =
4526                 {
4527                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
4528                         0u,                                                                                     // uint32_t                                     bufferRowLength;
4529                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
4530                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
4531                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
4532                         defaultExtent                                                           // VkExtent3D                           imageExtent;
4533                 };
4534                 CopyRegion      copyRegion;
4535                 copyRegion.bufferImageCopy      = bufferImageCopy;
4536
4537                 params.regions.push_back(copyRegion);
4538
4539                 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
4540         }
4541
4542         {
4543                 TestParams      params;
4544                 params.src.buffer.size                          = defaultSize * defaultSize;
4545                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4546                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4547                 params.dst.image.extent                         = defaultExtent;
4548                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4549                 params.allocationKind                           = allocationKind;
4550
4551                 CopyRegion      region;
4552                 deUint32        divisor = 1;
4553                 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
4554                 {
4555                         const VkBufferImageCopy bufferImageCopy =
4556                         {
4557                                 0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
4558                                 0u,                                                                                                                             // uint32_t                                     bufferRowLength;
4559                                 0u,                                                                                                                             // uint32_t                                     bufferImageHeight;
4560                                 defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
4561                                 {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
4562                                 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
4563                         };
4564                         region.bufferImageCopy  = bufferImageCopy;
4565                         params.regions.push_back(region);
4566                 }
4567
4568                 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
4569         }
4570
4571         {
4572                 TestParams      params;
4573                 params.src.buffer.size                          = defaultSize * defaultSize;
4574                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4575                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4576                 params.dst.image.extent                         = defaultExtent;
4577                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4578                 params.allocationKind                           = allocationKind;
4579
4580                 const VkBufferImageCopy bufferImageCopy =
4581                 {
4582                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
4583                         defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferRowLength;
4584                         defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferImageHeight;
4585                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
4586                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
4587                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
4588                 };
4589                 CopyRegion      copyRegion;
4590                 copyRegion.bufferImageCopy      = bufferImageCopy;
4591
4592                 params.regions.push_back(copyRegion);
4593
4594                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
4595         }
4596 }
4597
4598 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4599 {
4600         tcu::TestContext&                               testCtx                                 = group->getTestContext();
4601
4602         {
4603                 TestParams                      params;
4604                 params.src.buffer.size  = defaultSize;
4605                 params.dst.buffer.size  = defaultSize;
4606                 params.allocationKind   = allocationKind;
4607
4608                 const VkBufferCopy      bufferCopy      =
4609                 {
4610                         0u,                             // VkDeviceSize srcOffset;
4611                         0u,                             // VkDeviceSize dstOffset;
4612                         defaultSize,    // VkDeviceSize size;
4613                 };
4614
4615                 CopyRegion      copyRegion;
4616                 copyRegion.bufferCopy   = bufferCopy;
4617                 params.regions.push_back(copyRegion);
4618
4619                 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
4620         }
4621
4622         {
4623                 TestParams                      params;
4624                 params.src.buffer.size  = defaultFourthSize;
4625                 params.dst.buffer.size  = defaultFourthSize;
4626                 params.allocationKind   = allocationKind;
4627
4628                 const VkBufferCopy      bufferCopy      =
4629                 {
4630                         12u,    // VkDeviceSize srcOffset;
4631                         4u,             // VkDeviceSize dstOffset;
4632                         1u,             // VkDeviceSize size;
4633                 };
4634
4635                 CopyRegion      copyRegion;
4636                 copyRegion.bufferCopy = bufferCopy;
4637                 params.regions.push_back(copyRegion);
4638
4639                 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
4640         }
4641
4642         {
4643                 const deUint32          size            = 16;
4644                 TestParams                      params;
4645                 params.src.buffer.size  = size;
4646                 params.dst.buffer.size  = size * (size + 1);
4647                 params.allocationKind   = allocationKind;
4648
4649                 // Copy region with size 1..size
4650                 for (unsigned int i = 1; i <= size; i++)
4651                 {
4652                         const VkBufferCopy      bufferCopy      =
4653                         {
4654                                 0,                      // VkDeviceSize srcOffset;
4655                                 i * size,       // VkDeviceSize dstOffset;
4656                                 i,                      // VkDeviceSize size;
4657                         };
4658
4659                         CopyRegion      copyRegion;
4660                         copyRegion.bufferCopy = bufferCopy;
4661                         params.regions.push_back(copyRegion);
4662                 }
4663
4664                 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
4665         }
4666 }
4667
4668 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4669 {
4670         tcu::TestContext&       testCtx                 = group->getTestContext();
4671         TestParams                      params;
4672         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4673         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4674         params.src.image.extent                         = defaultExtent;
4675         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4676         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4677         params.dst.image.extent                         = defaultExtent;
4678         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4679         params.allocationKind                           = allocationKind;
4680
4681         {
4682                 const VkImageBlit                               imageBlit =
4683                 {
4684                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4685                         {
4686                                 { 0, 0, 0 },
4687                                 { defaultSize, defaultSize, 1 }
4688                         },                                      // VkOffset3D                           srcOffsets[2];
4689
4690                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4691                         {
4692                                 { 0, 0, 0 },
4693                                 { defaultSize, defaultSize, 1 }
4694                         }                                       // VkOffset3D                           dstOffset[2];
4695                 };
4696
4697                 CopyRegion      region;
4698                 region.imageBlit = imageBlit;
4699                 params.regions.push_back(region);
4700         }
4701
4702         // Filter is VK_FILTER_NEAREST.
4703         {
4704                 params.filter                                   = VK_FILTER_NEAREST;
4705                 const std::string description   = "Nearest filter";
4706
4707                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4708                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
4709
4710                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4711                 const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
4712                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4713
4714                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4715                 const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4716                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4717         }
4718
4719         // Filter is VK_FILTER_LINEAR.
4720         {
4721                 params.filter                                   = VK_FILTER_LINEAR;
4722                 const std::string description   = "Linear filter";
4723
4724                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4725                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
4726
4727                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4728                 const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
4729                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4730
4731                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4732                 const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4733                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4734         }
4735 }
4736
4737 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4738 {
4739         tcu::TestContext&       testCtx                 = group->getTestContext();
4740         TestParams                      params;
4741         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4742         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4743         params.src.image.extent                         = defaultExtent;
4744         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4745         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4746         params.dst.image.extent                         = defaultExtent;
4747         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4748         params.allocationKind                           = allocationKind;
4749
4750         {
4751                 const VkImageBlit                               imageBlit       =
4752                 {
4753                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4754                         {
4755                                 {0, 0, 0},
4756                                 {defaultSize, defaultSize, 1}
4757                         },                                      // VkOffset3D                           srcOffsets[2];
4758
4759                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4760                         {
4761                                 {defaultSize, defaultSize, 0},
4762                                 {0, 0, 1}
4763                         }                                       // VkOffset3D                           dstOffset[2];
4764                 };
4765
4766                 CopyRegion      region;
4767                 region.imageBlit = imageBlit;
4768                 params.regions.push_back(region);
4769         }
4770
4771         // Filter is VK_FILTER_NEAREST.
4772         {
4773                 params.filter                                   = VK_FILTER_NEAREST;
4774                 const std::string description   = "Nearest filter";
4775
4776                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4777                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
4778
4779                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4780                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4781                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4782
4783                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4784                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4785                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4786         }
4787
4788         // Filter is VK_FILTER_LINEAR.
4789         {
4790                 params.filter                                   = VK_FILTER_LINEAR;
4791                 const std::string description   = "Linear filter";
4792
4793                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4794                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
4795
4796                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4797                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4798                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4799
4800                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4801                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4802                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4803         }
4804 }
4805
4806 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4807 {
4808         tcu::TestContext&       testCtx                 = group->getTestContext();
4809         TestParams                      params;
4810         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4811         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4812         params.src.image.extent                         = defaultExtent;
4813         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4814         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4815         params.dst.image.extent                         = defaultExtent;
4816         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4817         params.allocationKind                           = allocationKind;
4818
4819         {
4820                 const VkImageBlit                               imageBlit       =
4821                 {
4822                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4823                         {
4824                                 {0, 0, 0},
4825                                 {defaultSize, defaultSize, 1}
4826                         },                                      // VkOffset3D                           srcOffsets[2];
4827
4828                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4829                         {
4830                                 {defaultSize, 0, 0},
4831                                 {0, defaultSize, 1}
4832                         }                                       // VkOffset3D                           dstOffset[2];
4833                 };
4834
4835                 CopyRegion      region;
4836                 region.imageBlit = imageBlit;
4837                 params.regions.push_back(region);
4838         }
4839
4840         // Filter is VK_FILTER_NEAREST.
4841         {
4842                 params.filter                                   = VK_FILTER_NEAREST;
4843                 const std::string description   = "Nearest filter";
4844
4845                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4846                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
4847
4848                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4849                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4850                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4851
4852                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4853                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4854                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4855         }
4856
4857         // Filter is VK_FILTER_LINEAR.
4858         {
4859                 params.filter                                   = VK_FILTER_LINEAR;
4860                 const std::string description   = "Linear filter";
4861
4862                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4863                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
4864
4865                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4866                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4867                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4868
4869                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4870                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4871                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4872         }
4873 }
4874
4875 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4876 {
4877         tcu::TestContext&       testCtx                 = group->getTestContext();
4878         TestParams                      params;
4879         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4880         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4881         params.src.image.extent                         = defaultExtent;
4882         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4883         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4884         params.dst.image.extent                         = defaultExtent;
4885         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4886         params.allocationKind                           = allocationKind;
4887
4888         {
4889                 const VkImageBlit                               imageBlit       =
4890                 {
4891                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4892                         {
4893                                 {0, 0, 0},
4894                                 {defaultSize, defaultSize, 1}
4895                         },                                      // VkOffset3D                           srcOffsets[2];
4896
4897                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4898                         {
4899                                 {0, defaultSize, 0},
4900                                 {defaultSize, 0, 1}
4901                         }                                       // VkOffset3D                           dstOffset[2];
4902                 };
4903
4904                 CopyRegion      region;
4905                 region.imageBlit = imageBlit;
4906                 params.regions.push_back(region);
4907         }
4908
4909         // Filter is VK_FILTER_NEAREST.
4910         {
4911                 params.filter                                   = VK_FILTER_NEAREST;
4912                 const std::string description   = "Nearest filter";
4913
4914                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4915                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
4916
4917                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4918                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4919                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4920
4921                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4922                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4923                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4924         }
4925
4926         // Filter is VK_FILTER_LINEAR.
4927         {
4928                 params.filter                                   = VK_FILTER_LINEAR;
4929                 const std::string description   = "Linear filter";
4930
4931                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4932                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
4933
4934                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4935                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4936                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4937
4938                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4939                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4940                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4941         }
4942 }
4943
4944 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4945 {
4946         tcu::TestContext&       testCtx                 = group->getTestContext();
4947         TestParams                      params;
4948         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
4949         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
4950         params.src.image.extent                         = defaultExtent;
4951         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4952         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
4953         params.dst.image.extent                         = defaultExtent;
4954         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4955         params.allocationKind                           = allocationKind;
4956
4957         // No mirroring.
4958         {
4959                 const VkImageBlit                               imageBlit       =
4960                 {
4961                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4962                         {
4963                                 {0, 0, 0},
4964                                 {defaultHalfSize, defaultHalfSize, 1}
4965                         },                                      // VkOffset3D                           srcOffsets[2];
4966
4967                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4968                         {
4969                                 {0, 0, 0},
4970                                 {defaultHalfSize, defaultHalfSize, 1}
4971                         }                                       // VkOffset3D                           dstOffset[2];
4972                 };
4973
4974                 CopyRegion      region;
4975                 region.imageBlit = imageBlit;
4976                 params.regions.push_back(region);
4977         }
4978
4979         // Flipping y coordinates.
4980         {
4981                 const VkImageBlit                               imageBlit       =
4982                 {
4983                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4984                         {
4985                                 {defaultHalfSize, 0, 0},
4986                                 {defaultSize, defaultHalfSize, 1}
4987                         },                                      // VkOffset3D                           srcOffsets[2];
4988
4989                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4990                         {
4991                                 {defaultHalfSize, defaultHalfSize, 0},
4992                                 {defaultSize, 0, 1}
4993                         }                                       // VkOffset3D                           dstOffset[2];
4994                 };
4995
4996                 CopyRegion      region;
4997                 region.imageBlit = imageBlit;
4998                 params.regions.push_back(region);
4999         }
5000
5001         // Flipping x coordinates.
5002         {
5003                 const VkImageBlit                               imageBlit       =
5004                 {
5005                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5006                         {
5007                                 {0, defaultHalfSize, 0},
5008                                 {defaultHalfSize, defaultSize, 1}
5009                         },                                      // VkOffset3D                           srcOffsets[2];
5010
5011                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5012                         {
5013                                 {defaultHalfSize, defaultHalfSize, 0},
5014                                 {0, defaultSize, 1}
5015                         }                                       // VkOffset3D                           dstOffset[2];
5016                 };
5017
5018                 CopyRegion      region;
5019                 region.imageBlit = imageBlit;
5020                 params.regions.push_back(region);
5021         }
5022
5023         // Flipping x and y coordinates.
5024         {
5025                 const VkImageBlit                               imageBlit       =
5026                 {
5027                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5028                         {
5029                                 {defaultHalfSize, defaultHalfSize, 0},
5030                                 {defaultSize, defaultSize, 1}
5031                         },                                      // VkOffset3D                           srcOffsets[2];
5032
5033                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5034                         {
5035                                 {defaultSize, defaultSize, 0},
5036                                 {defaultHalfSize, defaultHalfSize, 1}
5037                         }                                       // VkOffset3D                           dstOffset[2];
5038                 };
5039
5040                 CopyRegion      region;
5041                 region.imageBlit = imageBlit;
5042                 params.regions.push_back(region);
5043         }
5044
5045         // Filter is VK_FILTER_NEAREST.
5046         {
5047                 params.filter                                   = VK_FILTER_NEAREST;
5048                 const std::string description   = "Nearest filter";
5049
5050                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5051                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
5052
5053                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5054                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5055                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5056
5057                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5058                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5059                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5060         }
5061
5062         // Filter is VK_FILTER_LINEAR.
5063         {
5064                 params.filter                                   = VK_FILTER_LINEAR;
5065                 const std::string description   = "Linear filter";
5066
5067                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5068                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
5069
5070                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5071                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5072                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5073
5074                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5075                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5076                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5077         }
5078 }
5079
5080 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5081 {
5082         tcu::TestContext&       testCtx                 = group->getTestContext();
5083         TestParams                      params;
5084         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5085         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5086         params.src.image.extent                         = defaultExtent;
5087         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5088         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5089         params.dst.image.extent                         = defaultHalfExtent;
5090         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5091         params.allocationKind                           = allocationKind;
5092
5093         {
5094                 const VkImageBlit                               imageBlit       =
5095                 {
5096                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5097                         {
5098                                 {0, 0, 0},
5099                                 {defaultSize, defaultSize, 1}
5100                         },                                      // VkOffset3D                                   srcOffsets[2];
5101
5102                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5103                         {
5104                                 {0, 0, 0},
5105                                 {defaultHalfSize, defaultHalfSize, 1}
5106                         }                                       // VkOffset3D                                   dstOffset[2];
5107                 };
5108
5109                 CopyRegion      region;
5110                 region.imageBlit        = imageBlit;
5111                 params.regions.push_back(region);
5112         }
5113
5114         // Filter is VK_FILTER_NEAREST.
5115         {
5116                 params.filter                                   = VK_FILTER_NEAREST;
5117                 const std::string description   = "Nearest filter";
5118
5119                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5120                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
5121
5122                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5123                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5124                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5125
5126                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5127                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5128                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5129         }
5130
5131         // Filter is VK_FILTER_LINEAR.
5132         {
5133                 params.filter                                   = VK_FILTER_LINEAR;
5134                 const std::string description   = "Linear filter";
5135
5136                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5137                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
5138
5139                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5140                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" );
5141                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5142
5143                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5144                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5145                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5146         }
5147 }
5148
5149 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5150 {
5151         tcu::TestContext&       testCtx                 = group->getTestContext();
5152         TestParams                      params;
5153         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5154         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5155         params.src.image.extent                         = defaultHalfExtent;
5156         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5157         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5158         params.dst.image.extent                         = defaultExtent;
5159         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5160         params.allocationKind                           = allocationKind;
5161
5162         {
5163                 const VkImageBlit                               imageBlit       =
5164                 {
5165                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5166                         {
5167                                 {0, 0, 0},
5168                                 {defaultHalfSize, defaultHalfSize, 1}
5169                         },                                      // VkOffset3D                                   srcOffsets[2];
5170
5171                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5172                         {
5173                                 {0, 0, 0},
5174                                 {defaultSize, defaultSize, 1}
5175                         }                                       // VkOffset3D                                   dstOffset[2];
5176                 };
5177
5178                 CopyRegion      region;
5179                 region.imageBlit        = imageBlit;
5180                 params.regions.push_back(region);
5181         }
5182
5183         // Filter is VK_FILTER_NEAREST.
5184         {
5185                 params.filter                                   = VK_FILTER_NEAREST;
5186                 const std::string description   = "Nearest filter";
5187
5188                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5189                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
5190
5191                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5192                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5193                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5194
5195                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5196                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5197                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5198         }
5199
5200         // Filter is VK_FILTER_LINEAR.
5201         {
5202                 params.filter                                   = VK_FILTER_LINEAR;
5203                 const std::string description   = "Linear filter";
5204
5205                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5206                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
5207
5208                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5209                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5210                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5211
5212                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5213                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5214                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5215         }
5216 }
5217
5218 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5219 {
5220         tcu::TestContext&       testCtx                 = group->getTestContext();
5221         TestParams                      params;
5222         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5223         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5224         params.src.image.extent                         = defaultExtent;
5225         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5226         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5227         params.dst.image.extent                         = defaultExtent;
5228         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5229         params.allocationKind                           = allocationKind;
5230
5231         {
5232                 const VkImageBlit                               imageBlit       =
5233                 {
5234                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5235                         {
5236                                 {defaultFourthSize, defaultFourthSize, 0},
5237                                 {defaultFourthSize*3, defaultFourthSize*3, 1}
5238                         },                                      // VkOffset3D                                   srcOffsets[2];
5239
5240                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5241                         {
5242                                 {0, 0, 0},
5243                                 {defaultSize, defaultSize, 1}
5244                         }                                       // VkOffset3D                                   dstOffset[2];
5245                 };
5246
5247                 CopyRegion      region;
5248                 region.imageBlit        = imageBlit;
5249                 params.regions.push_back(region);
5250         }
5251
5252         // Filter is VK_FILTER_NEAREST.
5253         {
5254                 params.filter                                   = VK_FILTER_NEAREST;
5255                 const std::string description   = "Nearest filter";
5256
5257                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5258                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
5259
5260                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5261                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5262                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5263
5264                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5265                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5266                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5267         }
5268
5269         // Filter is VK_FILTER_LINEAR.
5270         {
5271                 params.filter                                   = VK_FILTER_LINEAR;
5272                 const std::string description   = "Linear filter";
5273
5274                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5275                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
5276
5277                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5278                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5279                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5280
5281                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5282                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5283                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5284         }
5285 }
5286
5287 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5288 {
5289         tcu::TestContext&       testCtx                 = group->getTestContext();
5290         TestParams                      params;
5291         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5292         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5293         params.src.image.extent                         = defaultExtent;
5294         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5295         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5296         params.dst.image.extent                         = defaultExtent;
5297         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5298         params.allocationKind                           = allocationKind;
5299
5300         {
5301                 CopyRegion      region;
5302                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
5303                 {
5304                         const VkImageBlit                       imageBlit       =
5305                         {
5306                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5307                                 {
5308                                         {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
5309                                         {defaultSize - i, defaultSize - i, 1}
5310                                 },                                      // VkOffset3D                                   srcOffsets[2];
5311
5312                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5313                                 {
5314                                         {i, i, 0},
5315                                         {i + defaultFourthSize, i + defaultFourthSize, 1}
5316                                 }                                       // VkOffset3D                                   dstOffset[2];
5317                         };
5318                         region.imageBlit        = imageBlit;
5319                         params.regions.push_back(region);
5320                 }
5321         }
5322
5323         // Filter is VK_FILTER_NEAREST.
5324         {
5325                 params.filter                                   = VK_FILTER_NEAREST;
5326                 const std::string description   = "Nearest filter";
5327
5328                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5329                 group->addChild(new BlittingTestCase(testCtx, "nearest", description, params));
5330
5331
5332                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5333                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5334                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5335
5336                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5337                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5338                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5339         }
5340
5341         // Filter is VK_FILTER_LINEAR.
5342         {
5343                 params.filter                                   = VK_FILTER_LINEAR;
5344                 const std::string description   = "Linear filter";
5345
5346                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5347                 group->addChild(new BlittingTestCase(testCtx, "linear", description, params));
5348
5349                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5350                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
5351                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5352
5353                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5354                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5355                 group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5356         }
5357 }
5358
5359 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5360 {
5361         addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind);
5362         addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind);
5363         addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind);
5364         addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind);
5365         addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind);
5366         addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind);
5367         addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind);
5368         addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind);
5369         addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind);
5370 }
5371
5372 struct BlitColorTestParams
5373 {
5374         TestParams              params;
5375         const VkFormat* compatibleFormats;
5376         bool                    onlyNearest;
5377 };
5378
5379 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
5380 {
5381         bool result = true;
5382
5383         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
5384         {
5385                 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
5386
5387                 result =
5388                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
5389                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
5390         }
5391
5392         return result;
5393 }
5394
5395
5396 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
5397 {
5398         tcu::TestContext& testCtx                               = group->getTestContext();
5399
5400         const VkImageLayout blitSrcLayouts[]    =
5401         {
5402                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5403                 VK_IMAGE_LAYOUT_GENERAL
5404         };
5405         const VkImageLayout blitDstLayouts[]    =
5406         {
5407                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5408                 VK_IMAGE_LAYOUT_GENERAL
5409         };
5410
5411         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
5412         {
5413                 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
5414                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
5415                 {
5416                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
5417
5418                         testParams.params.filter                        = VK_FILTER_NEAREST;
5419                         const std::string testName                      = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
5420                                                                                                   getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
5421                         const std::string description           = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
5422                                                                                                   " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
5423                         group->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, testParams.params));
5424
5425                         if (!testParams.onlyNearest)
5426                         {
5427                                 testParams.params.filter                = VK_FILTER_LINEAR;
5428                                 group->addChild(new BlittingTestCase(testCtx, testName + "_linear", description, testParams.params));
5429                         }
5430                 }
5431         }
5432 }
5433
5434 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
5435 {
5436         for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
5437         {
5438                 testParams.params.dst.image.format      = testParams.compatibleFormats[dstFormatIndex];
5439                 if (!isSupportedByFramework(testParams.params.dst.image.format))
5440                         continue;
5441
5442                 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
5443                         continue;
5444
5445                 const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
5446                 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
5447         }
5448 }
5449
5450 const VkFormat  compatibleFormatsUInts[]        =
5451 {
5452         VK_FORMAT_R8_UINT,
5453         VK_FORMAT_R8G8_UINT,
5454         VK_FORMAT_R8G8B8_UINT,
5455         VK_FORMAT_B8G8R8_UINT,
5456         VK_FORMAT_R8G8B8A8_UINT,
5457         VK_FORMAT_B8G8R8A8_UINT,
5458         VK_FORMAT_A8B8G8R8_UINT_PACK32,
5459         VK_FORMAT_A2R10G10B10_UINT_PACK32,
5460         VK_FORMAT_A2B10G10R10_UINT_PACK32,
5461         VK_FORMAT_R16_UINT,
5462         VK_FORMAT_R16G16_UINT,
5463         VK_FORMAT_R16G16B16_UINT,
5464         VK_FORMAT_R16G16B16A16_UINT,
5465         VK_FORMAT_R32_UINT,
5466         VK_FORMAT_R32G32_UINT,
5467         VK_FORMAT_R32G32B32_UINT,
5468         VK_FORMAT_R32G32B32A32_UINT,
5469         VK_FORMAT_R64_UINT,
5470         VK_FORMAT_R64G64_UINT,
5471         VK_FORMAT_R64G64B64_UINT,
5472         VK_FORMAT_R64G64B64A64_UINT,
5473
5474         VK_FORMAT_UNDEFINED
5475 };
5476 const VkFormat  compatibleFormatsSInts[]        =
5477 {
5478         VK_FORMAT_R8_SINT,
5479         VK_FORMAT_R8G8_SINT,
5480         VK_FORMAT_R8G8B8_SINT,
5481         VK_FORMAT_B8G8R8_SINT,
5482         VK_FORMAT_R8G8B8A8_SINT,
5483         VK_FORMAT_B8G8R8A8_SINT,
5484         VK_FORMAT_A8B8G8R8_SINT_PACK32,
5485         VK_FORMAT_A2R10G10B10_SINT_PACK32,
5486         VK_FORMAT_A2B10G10R10_SINT_PACK32,
5487         VK_FORMAT_R16_SINT,
5488         VK_FORMAT_R16G16_SINT,
5489         VK_FORMAT_R16G16B16_SINT,
5490         VK_FORMAT_R16G16B16A16_SINT,
5491         VK_FORMAT_R32_SINT,
5492         VK_FORMAT_R32G32_SINT,
5493         VK_FORMAT_R32G32B32_SINT,
5494         VK_FORMAT_R32G32B32A32_SINT,
5495         VK_FORMAT_R64_SINT,
5496         VK_FORMAT_R64G64_SINT,
5497         VK_FORMAT_R64G64B64_SINT,
5498         VK_FORMAT_R64G64B64A64_SINT,
5499
5500         VK_FORMAT_UNDEFINED
5501 };
5502 const VkFormat  compatibleFormatsFloats[]       =
5503 {
5504         VK_FORMAT_R4G4_UNORM_PACK8,
5505         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
5506         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
5507         VK_FORMAT_R5G6B5_UNORM_PACK16,
5508         VK_FORMAT_B5G6R5_UNORM_PACK16,
5509         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
5510         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
5511         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
5512         VK_FORMAT_R8_UNORM,
5513         VK_FORMAT_R8_SNORM,
5514         VK_FORMAT_R8_USCALED,
5515         VK_FORMAT_R8_SSCALED,
5516         VK_FORMAT_R8G8_UNORM,
5517         VK_FORMAT_R8G8_SNORM,
5518         VK_FORMAT_R8G8_USCALED,
5519         VK_FORMAT_R8G8_SSCALED,
5520         VK_FORMAT_R8G8B8_UNORM,
5521         VK_FORMAT_R8G8B8_SNORM,
5522         VK_FORMAT_R8G8B8_USCALED,
5523         VK_FORMAT_R8G8B8_SSCALED,
5524         VK_FORMAT_B8G8R8_UNORM,
5525         VK_FORMAT_B8G8R8_SNORM,
5526         VK_FORMAT_B8G8R8_USCALED,
5527         VK_FORMAT_B8G8R8_SSCALED,
5528         VK_FORMAT_R8G8B8A8_UNORM,
5529         VK_FORMAT_R8G8B8A8_SNORM,
5530         VK_FORMAT_R8G8B8A8_USCALED,
5531         VK_FORMAT_R8G8B8A8_SSCALED,
5532         VK_FORMAT_B8G8R8A8_UNORM,
5533         VK_FORMAT_B8G8R8A8_SNORM,
5534         VK_FORMAT_B8G8R8A8_USCALED,
5535         VK_FORMAT_B8G8R8A8_SSCALED,
5536         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
5537         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
5538         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
5539         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
5540         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
5541         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
5542         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
5543         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
5544         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
5545         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
5546         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
5547         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
5548         VK_FORMAT_R16_UNORM,
5549         VK_FORMAT_R16_SNORM,
5550         VK_FORMAT_R16_USCALED,
5551         VK_FORMAT_R16_SSCALED,
5552         VK_FORMAT_R16_SFLOAT,
5553         VK_FORMAT_R16G16_UNORM,
5554         VK_FORMAT_R16G16_SNORM,
5555         VK_FORMAT_R16G16_USCALED,
5556         VK_FORMAT_R16G16_SSCALED,
5557         VK_FORMAT_R16G16_SFLOAT,
5558         VK_FORMAT_R16G16B16_UNORM,
5559         VK_FORMAT_R16G16B16_SNORM,
5560         VK_FORMAT_R16G16B16_USCALED,
5561         VK_FORMAT_R16G16B16_SSCALED,
5562         VK_FORMAT_R16G16B16_SFLOAT,
5563         VK_FORMAT_R16G16B16A16_UNORM,
5564         VK_FORMAT_R16G16B16A16_SNORM,
5565         VK_FORMAT_R16G16B16A16_USCALED,
5566         VK_FORMAT_R16G16B16A16_SSCALED,
5567         VK_FORMAT_R16G16B16A16_SFLOAT,
5568         VK_FORMAT_R32_SFLOAT,
5569         VK_FORMAT_R32G32_SFLOAT,
5570         VK_FORMAT_R32G32B32_SFLOAT,
5571         VK_FORMAT_R32G32B32A32_SFLOAT,
5572         VK_FORMAT_R64_SFLOAT,
5573         VK_FORMAT_R64G64_SFLOAT,
5574         VK_FORMAT_R64G64B64_SFLOAT,
5575         VK_FORMAT_R64G64B64A64_SFLOAT,
5576 //      VK_FORMAT_B10G11R11_UFLOAT_PACK32,
5577 //      VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
5578 //      VK_FORMAT_BC1_RGB_UNORM_BLOCK,
5579 //      VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
5580 //      VK_FORMAT_BC2_UNORM_BLOCK,
5581 //      VK_FORMAT_BC3_UNORM_BLOCK,
5582 //      VK_FORMAT_BC4_UNORM_BLOCK,
5583 //      VK_FORMAT_BC4_SNORM_BLOCK,
5584 //      VK_FORMAT_BC5_UNORM_BLOCK,
5585 //      VK_FORMAT_BC5_SNORM_BLOCK,
5586 //      VK_FORMAT_BC6H_UFLOAT_BLOCK,
5587 //      VK_FORMAT_BC6H_SFLOAT_BLOCK,
5588 //      VK_FORMAT_BC7_UNORM_BLOCK,
5589 //      VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
5590 //      VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
5591 //      VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
5592 //      VK_FORMAT_EAC_R11_UNORM_BLOCK,
5593 //      VK_FORMAT_EAC_R11_SNORM_BLOCK,
5594 //      VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
5595 //      VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
5596 //      VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
5597 //      VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
5598 //      VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
5599 //      VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
5600 //      VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
5601 //      VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
5602 //      VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
5603 //      VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
5604 //      VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
5605 //      VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
5606 //      VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
5607 //      VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
5608 //      VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
5609 //      VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
5610
5611         VK_FORMAT_UNDEFINED
5612 };
5613 const VkFormat  compatibleFormatsSrgb[]         =
5614 {
5615         VK_FORMAT_R8_SRGB,
5616         VK_FORMAT_R8G8_SRGB,
5617         VK_FORMAT_R8G8B8_SRGB,
5618         VK_FORMAT_B8G8R8_SRGB,
5619         VK_FORMAT_R8G8B8A8_SRGB,
5620         VK_FORMAT_B8G8R8A8_SRGB,
5621         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5622 //      VK_FORMAT_BC1_RGB_SRGB_BLOCK,
5623 //      VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
5624 //      VK_FORMAT_BC2_SRGB_BLOCK,
5625 //      VK_FORMAT_BC3_SRGB_BLOCK,
5626 //      VK_FORMAT_BC7_SRGB_BLOCK,
5627 //      VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
5628 //      VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
5629 //      VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
5630 //      VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
5631 //      VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
5632 //      VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
5633 //      VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
5634 //      VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
5635 //      VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
5636 //      VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
5637 //      VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
5638 //      VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
5639 //      VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
5640 //      VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
5641 //      VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
5642 //      VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
5643 //      VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
5644
5645         VK_FORMAT_UNDEFINED
5646 };
5647
5648 const VkFormat  dedicatedAllocationBlittingFormatsToTest[]      =
5649 {
5650         // compatibleFormatsUInts
5651         VK_FORMAT_R8_UINT,
5652         VK_FORMAT_R64G64B64A64_UINT,
5653
5654         // compatibleFormatsSInts
5655         VK_FORMAT_R8_SINT,
5656         VK_FORMAT_R64G64B64A64_SINT,
5657
5658         // compatibleFormatsFloats
5659         VK_FORMAT_R4G4_UNORM_PACK8,
5660         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
5661
5662         // compatibleFormatsSrgb
5663         VK_FORMAT_R8_SRGB,
5664         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5665 };
5666
5667 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5668 {
5669         const struct {
5670                 const VkFormat* compatibleFormats;
5671                 const bool              onlyNearest;
5672         }       colorImageFormatsToTestBlit[]                   =
5673         {
5674                 { compatibleFormatsUInts,       true    },
5675                 { compatibleFormatsSInts,       true    },
5676                 { compatibleFormatsFloats,      false   },
5677                 { compatibleFormatsSrgb,        false   },
5678         };
5679
5680         const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
5681
5682         TestParams      params;
5683         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
5684         params.src.image.extent         = defaultExtent;
5685         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
5686         params.dst.image.extent         = defaultExtent;
5687         params.allocationKind           = allocationKind;
5688
5689         CopyRegion      region;
5690         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
5691         {
5692                 const VkImageBlit                       imageBlit       =
5693                 {
5694                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5695                         {
5696                                 {0, 0, 0},
5697                                 {defaultSize, defaultSize, 1}
5698                         },                                      // VkOffset3D                                   srcOffsets[2];
5699
5700                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5701                         {
5702                                 {i, 0, 0},
5703                                 {i + defaultFourthSize / j, defaultFourthSize / j, 1}
5704                         }                                       // VkOffset3D                                   dstOffset[2];
5705                 };
5706                 region.imageBlit        = imageBlit;
5707                 params.regions.push_back(region);
5708         }
5709         for (int i = 0; i < defaultSize; i += defaultFourthSize)
5710         {
5711                 const VkImageBlit                       imageBlit       =
5712                 {
5713                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5714                         {
5715                                 {i, i, 0},
5716                                 {i + defaultFourthSize, i + defaultFourthSize, 1}
5717                         },                                      // VkOffset3D                                   srcOffsets[2];
5718
5719                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5720                         {
5721                                 {i, defaultSize / 2, 0},
5722                                 {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
5723                         }                                       // VkOffset3D                                   dstOffset[2];
5724                 };
5725                 region.imageBlit        = imageBlit;
5726                 params.regions.push_back(region);
5727         }
5728
5729         if (allocationKind == ALLOCATION_KIND_DEDICATED)
5730         {
5731                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
5732                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
5733                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
5734         }
5735
5736         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
5737         {
5738                 const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
5739                 const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
5740                 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
5741                 {
5742                         params.src.image.format = compatibleFormats[srcFormatIndex];
5743                         if (!isSupportedByFramework(params.src.image.format))
5744                                 continue;
5745
5746                         BlitColorTestParams             testParams;
5747                         testParams.params                               = params;
5748                         testParams.compatibleFormats    = compatibleFormats;
5749                         testParams.onlyNearest                  = onlyNearest;
5750
5751                         const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
5752                         addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
5753                 }
5754         }
5755 }
5756
5757 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
5758 {
5759         const VkImageLayout blitSrcLayouts[]    =
5760         {
5761                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5762                 VK_IMAGE_LAYOUT_GENERAL
5763         };
5764         const VkImageLayout blitDstLayouts[]    =
5765         {
5766                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5767                 VK_IMAGE_LAYOUT_GENERAL
5768         };
5769
5770         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
5771         {
5772                 params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
5773
5774                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
5775                 {
5776                         params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
5777                         params.filter                                           = VK_FILTER_NEAREST;
5778
5779                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
5780                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
5781                         const std::string description   = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
5782                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
5783
5784                         group->addChild(new BlittingTestCase(group->getTestContext(), testName + "_nearest", description, params));
5785                 }
5786         }
5787 }
5788
5789 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5790 {
5791         const VkFormat  depthAndStencilFormats[]        =
5792         {
5793                 VK_FORMAT_D16_UNORM,
5794                 VK_FORMAT_X8_D24_UNORM_PACK32,
5795                 VK_FORMAT_D32_SFLOAT,
5796                 VK_FORMAT_S8_UINT,
5797                 VK_FORMAT_D16_UNORM_S8_UINT,
5798                 VK_FORMAT_D24_UNORM_S8_UINT,
5799                 VK_FORMAT_D32_SFLOAT_S8_UINT,
5800         };
5801
5802         const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
5803         const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
5804
5805         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
5806         {
5807                 TestParams      params;
5808                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5809                 params.src.image.extent                         = defaultExtent;
5810                 params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
5811                 params.dst.image.extent                         = defaultExtent;
5812                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5813                 params.dst.image.format                         = params.src.image.format;
5814                 params.allocationKind                           = allocationKind;
5815
5816                 CopyRegion      region;
5817                 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
5818                 {
5819                         const VkOffset3D        srcOffset0      = {0, 0, 0};
5820                         const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
5821                         const VkOffset3D        dstOffset0      = {i, 0, 0};
5822                         const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
5823
5824                         if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
5825                         {
5826                                 const VkImageBlit                       imageBlit       =
5827                                 {
5828                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
5829                                         { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
5830                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
5831                                         { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
5832                                 };
5833                                 region.imageBlit        = imageBlit;
5834                                 params.regions.push_back(region);
5835                         }
5836                         if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
5837                         {
5838                                 const VkImageBlit                       imageBlit       =
5839                                 {
5840                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
5841                                         { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
5842                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
5843                                         { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
5844                                 };
5845                                 region.imageBlit        = imageBlit;
5846                                 params.regions.push_back(region);
5847                         }
5848                 }
5849                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
5850                 {
5851                         const VkOffset3D        srcOffset0      = {i, i, 0};
5852                         const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
5853                         const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
5854                         const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
5855
5856                         if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
5857                         {
5858                                 const VkImageBlit                       imageBlit       =
5859                                 {
5860                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
5861                                         { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
5862                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
5863                                         { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
5864                                 };
5865                                 region.imageBlit        = imageBlit;
5866                                 params.regions.push_back(region);
5867                         }
5868                         if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
5869                         {
5870                                 const VkImageBlit                       imageBlit       =
5871                                 {
5872                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
5873                                         { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
5874                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
5875                                         { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
5876                                 };
5877                                 region.imageBlit        = imageBlit;
5878                                 params.regions.push_back(region);
5879                         }
5880                 }
5881
5882                 const std::string testName              = getFormatCaseName(params.src.image.format) + "_" +
5883                                                                                   getFormatCaseName(params.dst.image.format);
5884                 const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
5885                                                                                   " to " + getFormatCaseName(params.dst.image.format);
5886                 addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
5887         }
5888 }
5889
5890 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5891 {
5892         addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind);
5893         addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind);
5894 }
5895
5896 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5897 {
5898         addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind);
5899         addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind);
5900 }
5901
5902 const VkSampleCountFlagBits     samples[]               =
5903 {
5904         VK_SAMPLE_COUNT_2_BIT,
5905         VK_SAMPLE_COUNT_4_BIT,
5906         VK_SAMPLE_COUNT_8_BIT,
5907         VK_SAMPLE_COUNT_16_BIT,
5908         VK_SAMPLE_COUNT_32_BIT,
5909         VK_SAMPLE_COUNT_64_BIT
5910 };
5911 const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
5912
5913 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5914 {
5915         TestParams      params;
5916         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5917         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5918         params.src.image.extent                         = resolveExtent;
5919         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5920         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5921         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5922         params.dst.image.extent                         = resolveExtent;
5923         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5924         params.allocationKind                           = allocationKind;
5925
5926         {
5927                 const VkImageSubresourceLayers  sourceLayer     =
5928                 {
5929                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
5930                         0u,                                                     // uint32_t                             mipLevel;
5931                         0u,                                                     // uint32_t                             baseArrayLayer;
5932                         1u                                                      // uint32_t                             layerCount;
5933                 };
5934                 const VkImageResolve                    testResolve     =
5935                 {
5936                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
5937                         {0, 0, 0},              // VkOffset3D                           srcOffset;
5938                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
5939                         {0, 0, 0},              // VkOffset3D                           dstOffset;
5940                         resolveExtent,  // VkExtent3D                           extent;
5941                 };
5942
5943                 CopyRegion      imageResolve;
5944                 imageResolve.imageResolve       = testResolve;
5945                 params.regions.push_back(imageResolve);
5946         }
5947
5948         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
5949         {
5950                 params.samples                                  = samples[samplesIndex];
5951                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
5952                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
5953         }
5954 }
5955
5956 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5957 {
5958         TestParams      params;
5959         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5960         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5961         params.src.image.extent                         = resolveExtent;
5962         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5963         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5964         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
5965         params.dst.image.extent                         = resolveExtent;
5966         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5967         params.allocationKind                           = allocationKind;
5968
5969         {
5970                 const VkImageSubresourceLayers  sourceLayer     =
5971                 {
5972                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
5973                         0u,                                                     // uint32_t                             mipLevel;
5974                         0u,                                                     // uint32_t                             baseArrayLayer;
5975                         1u                                                      // uint32_t                             layerCount;
5976                 };
5977                 const VkImageResolve                    testResolve     =
5978                 {
5979                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
5980                         {0, 0, 0},              // VkOffset3D                           srcOffset;
5981                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
5982                         {64u, 64u, 0},          // VkOffset3D                           dstOffset;
5983                         {128u, 128u, 1u},       // VkExtent3D                           extent;
5984                 };
5985
5986                 CopyRegion      imageResolve;
5987                 imageResolve.imageResolve = testResolve;
5988                 params.regions.push_back(imageResolve);
5989         }
5990
5991         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
5992         {
5993                 params.samples                                  = samples[samplesIndex];
5994                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
5995                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
5996         }
5997 }
5998
5999 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6000 {
6001         TestParams      params;
6002         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6003         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6004         params.src.image.extent                         = resolveExtent;
6005         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6006         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6007         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6008         params.dst.image.extent                         = resolveExtent;
6009         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6010         params.allocationKind                           = allocationKind;
6011
6012         {
6013                 const VkImageSubresourceLayers  sourceLayer     =
6014                 {
6015                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6016                         0u,                                                     // uint32_t                             mipLevel;
6017                         0u,                                                     // uint32_t                             baseArrayLayer;
6018                         1u                                                      // uint32_t                             layerCount;
6019                 };
6020
6021                 for (int i = 0; i < 256; i += 64)
6022                 {
6023                         const VkImageResolve                    testResolve     =
6024                         {
6025                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
6026                                 {i, i, 0},              // VkOffset3D                           srcOffset;
6027                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
6028                                 {i, 0, 0},              // VkOffset3D                           dstOffset;
6029                                 {64u, 64u, 1u}, // VkExtent3D                           extent;
6030                         };
6031
6032                         CopyRegion      imageResolve;
6033                         imageResolve.imageResolve = testResolve;
6034                         params.regions.push_back(imageResolve);
6035                 }
6036         }
6037
6038         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
6039         {
6040                 params.samples                                  = samples[samplesIndex];
6041                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
6042                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
6043         }
6044 }
6045
6046 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6047 {
6048         TestParams      params;
6049         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6050         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6051         params.src.image.extent                         = defaultExtent;
6052         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6053         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6054         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6055         params.dst.image.extent                         = defaultExtent;
6056         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6057         params.allocationKind                           = allocationKind;
6058
6059         {
6060                 const VkImageSubresourceLayers  sourceLayer     =
6061                 {
6062                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6063                         0u,                                                     // uint32_t                             mipLevel;
6064                         0u,                                                     // uint32_t                             baseArrayLayer;
6065                         1u                                                      // uint32_t                             layerCount;
6066                 };
6067
6068                 const VkImageResolve                    testResolve     =
6069                 {
6070                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
6071                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
6072                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
6073                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
6074                         defaultExtent,          // VkExtent3D                           extent;
6075                 };
6076
6077                 CopyRegion      imageResolve;
6078                 imageResolve.imageResolve       = testResolve;
6079                 params.regions.push_back(imageResolve);
6080         }
6081
6082         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
6083         {
6084                 params.samples                                  = samples[samplesIndex];
6085                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
6086                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
6087         }
6088 }
6089
6090 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6091 {
6092         TestParams      params;
6093         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6094         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6095         params.src.image.extent                         = defaultExtent;
6096         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6097         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6098         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6099         params.dst.image.extent                         = defaultExtent;
6100         params.dst.image.extent.depth           = 5u;
6101         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6102         params.allocationKind                           = allocationKind;
6103
6104         for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
6105         {
6106                 const VkImageSubresourceLayers  sourceLayer     =
6107                 {
6108                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
6109                         0u,                                                             // uint32_t                             mipLevel;
6110                         layerNdx,                                               // uint32_t                             baseArrayLayer;
6111                         1u                                                              // uint32_t                             layerCount;
6112                 };
6113
6114                 const VkImageResolve                    testResolve     =
6115                 {
6116                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
6117                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
6118                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
6119                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
6120                         defaultExtent,          // VkExtent3D                           extent;
6121                 };
6122
6123                 CopyRegion      imageResolve;
6124                 imageResolve.imageResolve       = testResolve;
6125                 params.regions.push_back(imageResolve);
6126         }
6127
6128         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
6129         {
6130                 params.samples                                  = samples[samplesIndex];
6131                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
6132                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
6133         }
6134 }
6135
6136 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6137 {
6138         tcu::TestContext&       testCtx                 = group->getTestContext();
6139         TestParams                      params;
6140         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6141         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6142         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6143         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6144         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
6145         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6146         params.allocationKind                           = allocationKind;
6147
6148         {
6149                 const VkImageSubresourceLayers  sourceLayer     =
6150                 {
6151                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6152                         0u,                                                     // uint32_t                             mipLevel;
6153                         0u,                                                     // uint32_t                             baseArrayLayer;
6154                         1u                                                      // uint32_t                             layerCount;
6155                 };
6156                 const VkImageResolve                    testResolve     =
6157                 {
6158                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
6159                         {0, 0, 0},              // VkOffset3D                           srcOffset;
6160                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
6161                         {0, 0, 0},              // VkOffset3D                           dstOffset;
6162                         resolveExtent,  // VkExtent3D                           extent;
6163                 };
6164                 CopyRegion      imageResolve;
6165                 imageResolve.imageResolve       = testResolve;
6166                 params.regions.push_back(imageResolve);
6167         }
6168
6169         const VkExtent3D imageExtents[]         =
6170         {
6171                 { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
6172                 { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
6173                 { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
6174         };
6175
6176         for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
6177         {
6178                 const VkExtent3D&       srcImageSize    = imageExtents[srcImageExtentIndex];
6179                 params.src.image.extent                         = srcImageSize;
6180                 params.dst.image.extent                         = resolveExtent;
6181                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
6182                 {
6183                         params.samples  = samples[samplesIndex];
6184                         std::ostringstream testName;
6185                         testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
6186                         std::ostringstream description;
6187                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
6188                                                 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
6189                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
6190                 }
6191         }
6192         for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
6193         {
6194                 const VkExtent3D&       dstImageSize    = imageExtents[dstImageExtentIndex];
6195                 params.src.image.extent                         = resolveExtent;
6196                 params.dst.image.extent                         = dstImageSize;
6197                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
6198                 {
6199                         params.samples  = samples[samplesIndex];
6200                         std::ostringstream testName;
6201                         testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
6202                         std::ostringstream description;
6203                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
6204                                                 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
6205                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
6206                 }
6207         }
6208 }
6209
6210 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6211 {
6212         addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind);
6213         addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind);
6214         addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind);
6215         addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind);
6216         addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind);
6217         addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind);
6218 }
6219
6220 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6221 {
6222         addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
6223         addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
6224         addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
6225         addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
6226         addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
6227         addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
6228 }
6229
6230 void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group)
6231 {
6232         addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED);
6233 }
6234
6235 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
6236 {
6237         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED);
6238 }
6239
6240 } // anonymous
6241
6242 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
6243 {
6244         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
6245
6246         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core",                                       "Core Copies And Blitting Tests",                                                               addCoreCopiesAndBlittingTests));
6247         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",       "Copies And Blitting Tests For Dedicated Memory Allocation",    addDedicatedAllocationCopiesAndBlittingTests));
6248
6249         return copiesAndBlittingTests.release();
6250 }
6251
6252 } // api
6253 } // vkt