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