Merge vk-gl-cts/vulkan-cts-1.2.6 into vk-gl-cts/vulkan-cts-1.2.7
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015-2020 The Khronos Group Inc.
6  * Copyright (c) 2020 Google Inc.
7  * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan Copies And Blitting Tests
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktApiCopiesAndBlittingTests.hpp"
27
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30
31 #include "tcuImageCompare.hpp"
32 #include "tcuTexture.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "tcuVectorType.hpp"
35 #include "tcuVectorUtil.hpp"
36 #include "tcuTestLog.hpp"
37 #include "tcuTexLookupVerifier.hpp"
38
39 #include "vkImageUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRefUtil.hpp"
44 #include "vktTestCase.hpp"
45 #include "vktTestCaseUtil.hpp"
46 #include "vktTestGroupUtil.hpp"
47 #include "vkTypeUtil.hpp"
48 #include "vkCmdUtil.hpp"
49 #include "vkObjUtil.hpp"
50 #include "vkBuilderUtil.hpp"
51 #include "vkBufferWithMemory.hpp"
52 #include "vkBarrierUtil.hpp"
53
54 #include <set>
55 #include <array>
56 #include <algorithm>
57 #include <iterator>
58 #include <sstream>
59
60 namespace vkt
61 {
62
63 namespace api
64 {
65
66 namespace
67 {
68
69 enum FillMode
70 {
71         FILL_MODE_GRADIENT = 0,
72         FILL_MODE_WHITE,
73         FILL_MODE_RED,
74         FILL_MODE_MULTISAMPLE,
75         FILL_MODE_BLUE_RED_X,
76         FILL_MODE_BLUE_RED_Y,
77         FILL_MODE_BLUE_RED_Z,
78
79         FILL_MODE_LAST
80 };
81
82 enum MirrorModeBits
83 {
84         MIRROR_MODE_X           = (1<<0),
85         MIRROR_MODE_Y           = (1<<1),
86         MIRROR_MODE_Z           = (1<<2),
87         MIRROR_MODE_LAST        = (1<<3),
88 };
89
90 using MirrorMode = deUint32;
91
92 enum AllocationKind
93 {
94         ALLOCATION_KIND_SUBALLOCATED,
95         ALLOCATION_KIND_DEDICATED,
96 };
97
98 enum ExtensionUse
99 {
100         EXTENSION_USE_NONE,
101         EXTENSION_USE_COPY_COMMANDS2,
102 };
103
104 template <typename Type>
105 class BinaryCompare
106 {
107 public:
108         bool operator() (const Type& a, const Type& b) const
109         {
110                 return deMemCmp(&a, &b, sizeof(Type)) < 0;
111         }
112 };
113
114 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >    FormatSet;
115
116 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
117 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
118
119 using namespace vk;
120
121 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
122 {
123         const VkImageCopy2KHR   imageCopy2 =
124         {
125                 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,             // VkStructureType                              sType;
126                 DE_NULL,                                                                // const void*                                  pNext;
127                 imageCopy.srcSubresource,                               // VkImageSubresourceLayers             srcSubresource;
128                 imageCopy.srcOffset,                                    // VkOffset3D                                   srcOffset;
129                 imageCopy.dstSubresource,                               // VkImageSubresourceLayers             dstSubresource;
130                 imageCopy.dstOffset,                                    // VkOffset3D                                   dstOffset;
131                 imageCopy.extent                                                // VkExtent3D                                   extent;
132         };
133         return imageCopy2;
134 }
135 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
136 {
137         const VkBufferCopy2KHR  bufferCopy2 =
138         {
139                 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,    // VkStructureType                              sType;
140                 DE_NULL,                                                                // const void*                                  pNext;
141                 bufferCopy.srcOffset,                                   // VkDeviceSize                                 srcOffset;
142                 bufferCopy.dstOffset,                                   // VkDeviceSize                                 dstOffset;
143                 bufferCopy.size,                                                // VkDeviceSize                                 size;
144         };
145         return bufferCopy2;
146 }
147
148 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
149 {
150         const VkBufferImageCopy2KHR     bufferImageCopy2 =
151         {
152                 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,      // VkStructureType                              sType;
153                 DE_NULL,                                                                        // const void*                                  pNext;
154                 bufferImageCopy.bufferOffset,                           // VkDeviceSize                                 bufferOffset;
155                 bufferImageCopy.bufferRowLength,                        // uint32_t                                             bufferRowLength;
156                 bufferImageCopy.bufferImageHeight,                      // uint32_t                                             bufferImageHeight;
157                 bufferImageCopy.imageSubresource,                       // VkImageSubresourceLayers             imageSubresource;
158                 bufferImageCopy.imageOffset,                            // VkOffset3D                                   imageOffset;
159                 bufferImageCopy.imageExtent                                     // VkExtent3D                                   imageExtent;
160         };
161         return bufferImageCopy2;
162 }
163
164 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
165 {
166         const VkImageBlit2KHR   imageBlit2 =
167         {
168                 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,                     // VkStructureType                              sType;
169                 DE_NULL,                                                                        // const void*                                  pNext;
170                 imageBlit.srcSubresource,                                       // VkImageSubresourceLayers             srcSubresource;
171                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
172                         {
173                                 imageBlit.srcOffsets[0].x,                              // VkOffset3D                   srcOffsets[0].x;
174                                 imageBlit.srcOffsets[0].y,                              // VkOffset3D                   srcOffsets[0].y;
175                                 imageBlit.srcOffsets[0].z                               // VkOffset3D                   srcOffsets[0].z;
176                         },
177                         {
178                                 imageBlit.srcOffsets[1].x,                              // VkOffset3D                   srcOffsets[1].x;
179                                 imageBlit.srcOffsets[1].y,                              // VkOffset3D                   srcOffsets[1].y;
180                                 imageBlit.srcOffsets[1].z                               // VkOffset3D                   srcOffsets[1].z;
181                         }
182                 },
183                 imageBlit.dstSubresource,                                       // VkImageSubresourceLayers             dstSubresource;
184                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
185                         {
186                                 imageBlit.dstOffsets[0].x,                              // VkOffset3D                   dstOffsets[0].x;
187                                 imageBlit.dstOffsets[0].y,                              // VkOffset3D                   dstOffsets[0].y;
188                                 imageBlit.dstOffsets[0].z                               // VkOffset3D                   dstOffsets[0].z;
189                         },
190                         {
191                                 imageBlit.dstOffsets[1].x,                              // VkOffset3D                   dstOffsets[1].x;
192                                 imageBlit.dstOffsets[1].y,                              // VkOffset3D                   dstOffsets[1].y;
193                                 imageBlit.dstOffsets[1].z                               // VkOffset3D                   dstOffsets[1].z;
194                         }
195                 }
196         };
197         return imageBlit2;
198 }
199
200 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
201 {
202         const VkImageResolve2KHR        imageResolve2 =
203         {
204                 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,          // VkStructureType                              sType;
205                 DE_NULL,                                                                        // const void*                                  pNext;
206                 imageResolve.srcSubresource,                            // VkImageSubresourceLayers             srcSubresource;
207                 imageResolve.srcOffset,                                         // VkOffset3D                                   srcOffset;
208                 imageResolve.dstSubresource,                            // VkImageSubresourceLayers             dstSubresource;
209                 imageResolve.dstOffset,                                         // VkOffset3D                                   dstOffset;
210                 imageResolve.extent                                                     // VkExtent3D                                   extent;
211         };
212         return imageResolve2;
213 }
214
215 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
216 {
217         VkImageAspectFlags      aspectFlag      = 0;
218         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
219         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
220
221         if (!aspectFlag)
222                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
223
224         return aspectFlag;
225 }
226
227 VkImageAspectFlags getAspectFlags (VkFormat format)
228 {
229         if (isCompressedFormat(format))
230                 return VK_IMAGE_ASPECT_COLOR_BIT;
231         else
232                 return getAspectFlags(mapVkFormat(format));
233 }
234
235 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
236 {
237         if (isCompressedFormat(format))
238                 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
239         else
240                 return mapVkFormat(format);
241 }
242
243 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
244 // except that it supports some formats that are not mappable to VkFormat.
245 // When we are checking combined depth and stencil formats, each aspect is
246 // checked separately, and in some cases we construct PBA with a format that
247 // is not mappable to VkFormat.
248 bool isFloatFormat (tcu::TextureFormat format)
249 {
250         return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
251 }
252
253 union CopyRegion
254 {
255         VkBufferCopy                    bufferCopy;
256         VkImageCopy                             imageCopy;
257         VkBufferImageCopy               bufferImageCopy;
258         VkImageBlit                             imageBlit;
259         VkImageResolve                  imageResolve;
260 };
261
262 struct ImageParms
263 {
264         VkImageType                     imageType;
265         VkFormat                        format;
266         VkExtent3D                      extent;
267         VkImageTiling           tiling;
268         VkImageLayout           operationLayout;
269         VkImageCreateFlags      createFlags;
270         FillMode                        fillMode;
271 };
272
273 struct TestParams
274 {
275         union Data
276         {
277                 struct Buffer
278                 {
279                         VkDeviceSize    size;
280                 } buffer;
281
282                 ImageParms      image;
283         } src, dst;
284
285         std::vector<CopyRegion> regions;
286
287         union
288         {
289                 VkFilter                                filter;
290                 VkSampleCountFlagBits   samples;
291         };
292
293         AllocationKind  allocationKind;
294         ExtensionUse    extensionUse;
295         deUint32                mipLevels;
296         deBool                  singleCommand;
297         deUint32                barrierCount;
298         deBool                  separateDepthStencilLayouts;
299         deBool                  clearDestination;
300
301         TestParams (void)
302         {
303                 allocationKind                          = ALLOCATION_KIND_DEDICATED;
304                 extensionUse                            = EXTENSION_USE_NONE;
305                 mipLevels                                       = 1u;
306                 singleCommand                           = DE_TRUE;
307                 barrierCount                            = 1u;
308                 separateDepthStencilLayouts     = DE_FALSE;
309                 src.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
310                 dst.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
311                 src.image.fillMode                      = FILL_MODE_GRADIENT;
312                 dst.image.fillMode                      = FILL_MODE_WHITE;
313                 clearDestination                        = DE_FALSE;
314         }
315 };
316
317 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&        vki,
318                                                                                 const DeviceInterface&          vkd,
319                                                                                 const VkPhysicalDevice&         physDevice,
320                                                                                 const VkDevice                          device,
321                                                                                 const VkBuffer&                         buffer,
322                                                                                 const MemoryRequirement         requirement,
323                                                                                 Allocator&                                      allocator,
324                                                                                 AllocationKind                          allocationKind)
325 {
326         switch (allocationKind)
327         {
328                 case ALLOCATION_KIND_SUBALLOCATED:
329                 {
330                         const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
331
332                         return allocator.allocate(memoryRequirements, requirement);
333                 }
334
335                 case ALLOCATION_KIND_DEDICATED:
336                 {
337                         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
338                 }
339
340                 default:
341                 {
342                         TCU_THROW(InternalError, "Invalid allocation kind");
343                 }
344         }
345 }
346
347 de::MovePtr<Allocation> allocateImage (const InstanceInterface&         vki,
348                                                                            const DeviceInterface&               vkd,
349                                                                            const VkPhysicalDevice&              physDevice,
350                                                                            const VkDevice                               device,
351                                                                            const VkImage&                               image,
352                                                                            const MemoryRequirement              requirement,
353                                                                            Allocator&                                   allocator,
354                                                                            AllocationKind                               allocationKind)
355 {
356         switch (allocationKind)
357         {
358                 case ALLOCATION_KIND_SUBALLOCATED:
359                 {
360                         const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
361
362                         return allocator.allocate(memoryRequirements, requirement);
363                 }
364
365                 case ALLOCATION_KIND_DEDICATED:
366                 {
367                         return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
368                 }
369
370                 default:
371                 {
372                         TCU_THROW(InternalError, "Invalid allocation kind");
373                 }
374         }
375 }
376
377
378 inline deUint32 getArraySize(const ImageParms& parms)
379 {
380         return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
381 }
382
383 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
384 {
385         if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
386                 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
387         else
388                 return parms.createFlags;
389 }
390
391 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
392 {
393         const bool                      isCompressed    = isCompressedFormat(parms.format);
394         const deUint32          blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
395         const deUint32          blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
396
397         if (isCompressed && mipLevel != 0u)
398                 DE_FATAL("Not implemented");
399
400         const VkExtent3D        extent                  =
401         {
402                 (parms.extent.width >> mipLevel) * blockWidth,
403                 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
404                 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
405         };
406         return extent;
407 }
408
409 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
410 {
411         tcu::TextureFormat format;
412         switch (combinedFormat.type)
413         {
414                 case tcu::TextureFormat::UNORM_INT16:
415                 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
416                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
417                         break;
418                 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
419                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
420                         break;
421                 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
422                 case tcu::TextureFormat::FLOAT:
423                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
424                         break;
425                 default:
426                         DE_ASSERT(false);
427                         break;
428         }
429         return format;
430 }
431
432 class CopiesAndBlittingTestInstance : public vkt::TestInstance
433 {
434 public:
435                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
436                                                                                                                                                          TestParams     testParams);
437         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
438
439 protected:
440         const TestParams                                        m_params;
441
442         Move<VkCommandPool>                                     m_cmdPool;
443         Move<VkCommandBuffer>                           m_cmdBuffer;
444         Move<VkFence>                                           m_fence;
445         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
446         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
447         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel[16];
448
449         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
450
451         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
452         virtual void                                            generateExpectedResult                          (void);
453         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
454         void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
455         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
456         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
457         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
458                                                                                 {
459                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
460                                                                                 }
461
462         de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
463                                                                                                                                                          const ImageParms&                      imageParms,
464                                                                                                                                                          const deUint32                         mipLevel = 0u);
465
466 private:
467         void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
468                                                                                                                                                          const VkImage&                                         dst,
469                                                                                                                                                          const ImageParms&                                      parms,
470                                                                                                                                                          const deUint32                                         mipLevels = 1u);
471         void                                                            readImageAspect                                         (vk::VkImage                                            src,
472                                                                                                                                                          const tcu::PixelBufferAccess&          dst,
473                                                                                                                                                          const ImageParms&                                      parms,
474                                                                                                                                                          const deUint32                                         mipLevel = 0u);
475 };
476
477 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
478         : vkt::TestInstance     (context)
479         , m_params                      (testParams)
480 {
481         const DeviceInterface&          vk                                      = context.getDeviceInterface();
482         const VkDevice                          vkDevice                        = context.getDevice();
483         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
484
485         // Create command pool
486         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
487
488         // Create command buffer
489         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
490
491         // Create fence
492         m_fence = createFence(vk, vkDevice);
493 }
494
495 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
496 {
497         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(buffer.getFormat().type);
498         tcu::Vec4                                               maxValue                (1.0f);
499
500         if (buffer.getFormat().order == tcu::TextureFormat::S)
501         {
502                 // Stencil-only is stored in the first component. Stencil is always 8 bits.
503                 maxValue.x() = 1 << 8;
504         }
505         else if (buffer.getFormat().order == tcu::TextureFormat::DS)
506         {
507                 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
508                 maxValue.w() = 1 << 8;
509         }
510         else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
511         {
512                 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
513                 const tcu::IVec4        bits    = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
514                 const int                       signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
515
516                 for (int i = 0; i < 4; ++i)
517                 {
518                         if (bits[i] != 0)
519                                 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
520                 }
521         }
522
523         if (mode == FILL_MODE_GRADIENT)
524         {
525                 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
526                 return;
527         }
528
529         const tcu::Vec4         redColor        (maxValue.x(),  0.0,                    0.0,                    maxValue.w());
530         const tcu::Vec4         greenColor      (0.0,                   maxValue.y(),   0.0,                    maxValue.w());
531         const tcu::Vec4         blueColor       (0.0,                   0.0,                    maxValue.z(),   maxValue.w());
532         const tcu::Vec4         whiteColor      (maxValue.x(),  maxValue.y(),   maxValue.z(),   maxValue.w());
533
534         for (int z = 0; z < depth;  ++z)
535         for (int y = 0; y < height; ++y)
536         for (int x = 0; x < width;  ++x)
537         {
538                 switch (mode)
539                 {
540                         case FILL_MODE_WHITE:
541                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
542                                 {
543                                         buffer.setPixDepth(1.0f, x, y, z);
544                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
545                                                 buffer.setPixStencil(255, x, y, z);
546                                 }
547                                 else
548                                         buffer.setPixel(whiteColor, x, y, z);
549                                 break;
550
551                         case FILL_MODE_RED:
552                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
553                                 {
554                                         buffer.setPixDepth(redColor[0], x, y, z);
555                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
556                                                 buffer.setPixStencil((int)redColor[3], x, y, z);
557                                 }
558                                 else
559                                         buffer.setPixel(redColor, x, y, z);
560                                 break;
561
562                         case FILL_MODE_BLUE_RED_X:
563                         case FILL_MODE_BLUE_RED_Y:
564                         case FILL_MODE_BLUE_RED_Z:
565                                 bool useBlue;
566                                 switch (mode)
567                                 {
568                                         case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
569                                         case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
570                                         case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
571                                         default: DE_ASSERT(false); break;
572                                 }
573                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
574                                 {
575                                         buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
576                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
577                                                 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
578                                 }
579                                 else
580                                         buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
581                                 break;
582
583                         case FILL_MODE_MULTISAMPLE:
584                         {
585                                 float xScaled = static_cast<float>(x) / static_cast<float>(width);
586                                 float yScaled = static_cast<float>(y) / static_cast<float>(height);
587                                 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
588                                 break;
589                         }
590
591                         default:
592                                 break;
593                 }
594         }
595 }
596
597 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
598 {
599         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
600         const VkDevice                          vkDevice        = m_context.getDevice();
601         const deUint32                          bufferSize      = calculateSize(bufferAccess);
602
603         // Write buffer data
604         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
605         flushAlloc(vk, vkDevice, bufferAlloc);
606 }
607
608 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
609 {
610         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
611         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
612         const VkPhysicalDevice                  vkPhysDevice            = m_context.getPhysicalDevice();
613         const VkDevice                                  vkDevice                        = m_context.getDevice();
614         const VkQueue                                   queue                           = m_context.getUniversalQueue();
615         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
616         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
617         Move<VkBuffer>                                  buffer;
618         const deUint32                                  bufferSize                      = calculateSize(imageAccess);
619         de::MovePtr<Allocation>                 bufferAlloc;
620         const deUint32                                  arraySize                       = getArraySize(parms);
621         const VkExtent3D                                imageExtent                     = getExtent3D(parms);
622         std::vector <VkBufferImageCopy> copyRegions;
623
624         // Create source buffer
625         {
626                 const VkBufferCreateInfo        bufferParams            =
627                 {
628                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
629                         DE_NULL,                                                                        // const void*                  pNext;
630                         0u,                                                                                     // VkBufferCreateFlags  flags;
631                         bufferSize,                                                                     // VkDeviceSize                 size;
632                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
633                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
634                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
635                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
636                 };
637
638                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
639                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
640                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
641         }
642
643         // Barriers for copying buffer to image
644         const VkBufferMemoryBarrier             preBufferBarrier        =
645         {
646                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
647                 DE_NULL,                                                                                // const void*          pNext;
648                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
649                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
650                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
651                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
652                 *buffer,                                                                                // VkBuffer                     buffer;
653                 0u,                                                                                             // VkDeviceSize         offset;
654                 bufferSize                                                                              // VkDeviceSize         size;
655         };
656
657         const VkImageAspectFlags                formatAspect            = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
658         const bool                                              skipPreImageBarrier     = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
659                                                                                                                   getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
660
661         const VkImageMemoryBarrier              preImageBarrier         =
662         {
663                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
664                 DE_NULL,                                                                                // const void*                          pNext;
665                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
666                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
667                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
668                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
669                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
670                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
671                 image,                                                                                  // VkImage                                      image;
672                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
673                         formatAspect,   // VkImageAspectFlags   aspect;
674                         0u,                             // deUint32                             baseMipLevel;
675                         mipLevels,              // deUint32                             mipLevels;
676                         0u,                             // deUint32                             baseArraySlice;
677                         arraySize,              // deUint32                             arraySize;
678                 }
679         };
680
681         const VkImageMemoryBarrier              postImageBarrier        =
682         {
683                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
684                 DE_NULL,                                                                                // const void*                          pNext;
685                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
686                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
687                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
688                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
689                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
690                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
691                 image,                                                                                  // VkImage                                      image;
692                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
693                         formatAspect,                           // VkImageAspectFlags   aspect;
694                         0u,                                                     // deUint32                             baseMipLevel;
695                         mipLevels,                                      // deUint32                             mipLevels;
696                         0u,                                                     // deUint32                             baseArraySlice;
697                         arraySize,                                      // deUint32                             arraySize;
698                 }
699         };
700
701         for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
702         {
703                 const VkExtent3D                copyExtent      =
704                 {
705                         imageExtent.width       >> mipLevelNdx,
706                         imageExtent.height      >> mipLevelNdx,
707                         imageExtent.depth
708                 };
709
710                 const bool              isCompressed    = isCompressedFormat(parms.format);
711                 const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
712                 const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
713                 deUint32 rowLength              = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
714                 deUint32 imageHeight    = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
715
716                 const VkBufferImageCopy copyRegion      =
717                 {
718                         0u,                                                                                             // VkDeviceSize                         bufferOffset;
719                         rowLength,                                                                              // deUint32                                     bufferRowLength;
720                         imageHeight,                                                                    // deUint32                                     bufferImageHeight;
721                         {
722                                 getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
723                                 mipLevelNdx,                                                                    // deUint32                             mipLevel;
724                                 0u,                                                                                             // deUint32                             baseArrayLayer;
725                                 arraySize,                                                                              // deUint32                             layerCount;
726                         },                                                                                              // VkImageSubresourceLayers     imageSubresource;
727                         { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
728                         copyExtent                                                                              // VkExtent3D                           imageExtent;
729                 };
730
731                 copyRegions.push_back(copyRegion);
732         }
733
734         // Write buffer data
735         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
736         flushAlloc(vk, vkDevice, *bufferAlloc);
737
738         // Copy buffer to image
739         beginCommandBuffer(vk, *m_cmdBuffer);
740         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
741                                                   1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
742         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
743         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);
744         endCommandBuffer(vk, *m_cmdBuffer);
745
746         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
747 }
748
749 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
750 {
751         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
752         {
753                 if (tcu::hasDepthComponent(src.getFormat().order))
754                 {
755                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
756                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
757                         uploadImageAspect(depthTexture.getAccess(), dst, parms);
758                 }
759
760                 if (tcu::hasStencilComponent(src.getFormat().order))
761                 {
762                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
763                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
764                         uploadImageAspect(stencilTexture.getAccess(), dst, parms);
765                 }
766         }
767         else
768                 uploadImageAspect(src, dst, parms, mipLevels);
769 }
770
771 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
772 {
773         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel[0]->getAccess();
774
775         if (isFloatFormat(result.getFormat()))
776         {
777                 const tcu::Vec4 threshold (0.0f);
778                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
779                         return tcu::TestStatus::fail("CopiesAndBlitting test");
780         }
781         else
782         {
783                 const tcu::UVec4 threshold (0u);
784                 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
785                 {
786                         if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
787                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
788                 }
789                 else
790                 {
791                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
792                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
793                 }
794         }
795
796         return tcu::TestStatus::pass("CopiesAndBlitting test");
797 }
798
799 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
800 {
801         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
802         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
803
804         m_expectedTextureLevel[0]       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
805         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
806
807         for (deUint32 i = 0; i < m_params.regions.size(); i++)
808                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
809 }
810
811 class CopiesAndBlittingTestCase : public vkt::TestCase
812 {
813 public:
814                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
815                                                                                                                  const std::string&                     name,
816                                                                                                                  const std::string&                     description)
817                                                                 : vkt::TestCase (testCtx, name, description)
818                                                         {}
819
820         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
821 };
822
823 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                        image,
824                                                                                                          const tcu::PixelBufferAccess&  dst,
825                                                                                                          const ImageParms&                              imageParms,
826                                                                                                          const deUint32                                 mipLevel)
827 {
828         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
829         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
830         const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
831         const VkDevice                          device                          = m_context.getDevice();
832         const VkQueue                           queue                           = m_context.getUniversalQueue();
833         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
834
835         Move<VkBuffer>                          buffer;
836         de::MovePtr<Allocation>         bufferAlloc;
837         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
838         const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
839         const VkExtent3D                        imageExtent                     = getExtent3D(imageParms, mipLevel);
840
841         // Create destination buffer
842         {
843                 const VkBufferCreateInfo                        bufferParams                    =
844                 {
845                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
846                         DE_NULL,                                                                        // const void*                  pNext;
847                         0u,                                                                                     // VkBufferCreateFlags  flags;
848                         pixelDataSize,                                                          // VkDeviceSize                 size;
849                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
850                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
851                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
852                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
853                 };
854
855                 buffer          = createBuffer(vk, device, &bufferParams);
856                 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
857                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
858
859                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
860                 flushAlloc(vk, device, *bufferAlloc);
861         }
862
863         // Barriers for copying image to buffer
864         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(imageParms.format);
865         const VkImageMemoryBarrier                              imageBarrier                    =
866         {
867                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
868                 DE_NULL,                                                                        // const void*                          pNext;
869                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
870                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
871                 imageParms.operationLayout,                                     // VkImageLayout                        oldLayout;
872                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
873                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
874                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
875                 image,                                                                          // VkImage                                      image;
876                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
877                         formatAspect,                   // VkImageAspectFlags   aspectMask;
878                         mipLevel,                               // deUint32                             baseMipLevel;
879                         1u,                                             // deUint32                             mipLevels;
880                         0u,                                             // deUint32                             baseArraySlice;
881                         getArraySize(imageParms)// deUint32                             arraySize;
882                 }
883         };
884
885         const VkBufferMemoryBarrier                             bufferBarrier                   =
886         {
887                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
888                 DE_NULL,                                                                        // const void*          pNext;
889                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
890                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
891                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
892                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
893                 *buffer,                                                                        // VkBuffer                     buffer;
894                 0u,                                                                                     // VkDeviceSize         offset;
895                 pixelDataSize                                                           // VkDeviceSize         size;
896         };
897
898         const VkImageMemoryBarrier                              postImageBarrier                =
899         {
900                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
901                 DE_NULL,                                                                        // const void*                          pNext;
902                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
903                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
904                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        oldLayout;
905                 imageParms.operationLayout,                                     // VkImageLayout                        newLayout;
906                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
907                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
908                 image,                                                                          // VkImage                                      image;
909                 {
910                         formatAspect,                                                           // VkImageAspectFlags   aspectMask;
911                         mipLevel,                                                                       // deUint32                             baseMipLevel;
912                         1u,                                                                                     // deUint32                             mipLevels;
913                         0u,                                                                                     // deUint32                             baseArraySlice;
914                         getArraySize(imageParms)                                        // deUint32                             arraySize;
915                 }                                                                                       // VkImageSubresourceRange      subresourceRange;
916         };
917
918         // Copy image to buffer
919         const bool              isCompressed    = isCompressedFormat(imageParms.format);
920         const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
921         const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
922         deUint32 rowLength              = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
923         deUint32 imageHeight    = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
924
925         const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
926         const VkBufferImageCopy         copyRegion              =
927         {
928                 0u,                                                             // VkDeviceSize                         bufferOffset;
929                 rowLength,                                              // deUint32                                     bufferRowLength;
930                 imageHeight,                                    // deUint32                                     bufferImageHeight;
931                 {
932                         aspect,                                                 // VkImageAspectFlags           aspect;
933                         mipLevel,                                               // deUint32                                     mipLevel;
934                         0u,                                                             // deUint32                                     baseArrayLayer;
935                         getArraySize(imageParms),               // deUint32                                     layerCount;
936                 },                                                              // VkImageSubresourceLayers     imageSubresource;
937                 { 0, 0, 0 },                                    // VkOffset3D                           imageOffset;
938                 imageExtent                                             // VkExtent3D                           imageExtent;
939         };
940
941         beginCommandBuffer(vk, *m_cmdBuffer);
942         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);
943         vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
944         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);
945         endCommandBuffer(vk, *m_cmdBuffer);
946
947         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
948
949         // Read buffer data
950         invalidateAlloc(vk, device, *bufferAlloc);
951         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
952 }
953
954 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage            image,
955                                                                                                                                                  const ImageParms&      parms,
956                                                                                                                                                  const deUint32         mipLevel)
957 {
958         const tcu::TextureFormat                imageFormat     = getSizeCompatibleTcuTextureFormat(parms.format);
959         de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
960
961         if (tcu::isCombinedDepthStencilType(imageFormat.type))
962         {
963                 if (tcu::hasDepthComponent(imageFormat.order))
964                 {
965                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
966                         readImageAspect(image, depthTexture.getAccess(), parms);
967                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
968                 }
969
970                 if (tcu::hasStencilComponent(imageFormat.order))
971                 {
972                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
973                         readImageAspect(image, stencilTexture.getAccess(), parms);
974                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
975                 }
976         }
977         else
978                 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
979
980         return resultLevel;
981 }
982
983 // Copy from image to image.
984
985 class CopyImageToImage : public CopiesAndBlittingTestInstance
986 {
987 public:
988                                                                                 CopyImageToImage                        (Context&       context,
989                                                                                                                                          TestParams params);
990         virtual tcu::TestStatus                         iterate                                         (void);
991
992 protected:
993         virtual tcu::TestStatus                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
994
995 private:
996         Move<VkImage>                                           m_source;
997         de::MovePtr<Allocation>                         m_sourceImageAlloc;
998         Move<VkImage>                                           m_destination;
999         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1000
1001         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1002 };
1003
1004 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1005         : CopiesAndBlittingTestInstance(context, params)
1006 {
1007         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1008         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1009         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1010         const VkDevice                          vkDevice                        = context.getDevice();
1011         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1012         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1013
1014         // Create source image
1015         {
1016                 const VkImageCreateInfo sourceImageParams               =
1017                 {
1018                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1019                         DE_NULL,                                                                // const void*                  pNext;
1020                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1021                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1022                         m_params.src.image.format,                              // VkFormat                             format;
1023                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1024                         1u,                                                                             // deUint32                             mipLevels;
1025                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1026                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1027                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1028                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1029                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1030                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1031                         1u,                                                                             // deUint32                             queueFamilyCount;
1032                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1033                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1034                 };
1035
1036                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
1037                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1038                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1039         }
1040
1041         // Create destination image
1042         {
1043                 const VkImageCreateInfo destinationImageParams  =
1044                 {
1045                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1046                         DE_NULL,                                                                // const void*                  pNext;
1047                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1048                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1049                         m_params.dst.image.format,                              // VkFormat                             format;
1050                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1051                         1u,                                                                             // deUint32                             mipLevels;
1052                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1053                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1054                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1055                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1056                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1057                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1058                         1u,                                                                             // deUint32                             queueFamilyCount;
1059                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1060                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1061                 };
1062
1063                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1064                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1065                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1066         }
1067 }
1068
1069 tcu::TestStatus CopyImageToImage::iterate (void)
1070 {
1071         const bool                                      srcCompressed           = isCompressedFormat(m_params.src.image.format);
1072         const bool                                      dstCompressed           = isCompressedFormat(m_params.dst.image.format);
1073
1074         const tcu::TextureFormat        srcTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1075         const tcu::TextureFormat        dstTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1076
1077         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1078                                                                                                                                                                 (int)m_params.src.image.extent.width,
1079                                                                                                                                                                 (int)m_params.src.image.extent.height,
1080                                                                                                                                                                 (int)m_params.src.image.extent.depth));
1081         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);
1082         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1083                                                                                                                                                                 (int)m_params.dst.image.extent.width,
1084                                                                                                                                                                 (int)m_params.dst.image.extent.height,
1085                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
1086         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.clearDestination ? FILL_MODE_WHITE : FILL_MODE_GRADIENT);
1087         generateExpectedResult();
1088
1089         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1090         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1091
1092         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1093         const VkDevice                          vkDevice                        = m_context.getDevice();
1094         const VkQueue                           queue                           = m_context.getUniversalQueue();
1095
1096         std::vector<VkImageCopy>                imageCopies;
1097         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
1098         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1099         {
1100                 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1101
1102                 // When copying between compressed and uncompressed formats the extent
1103                 // members represent the texel dimensions of the source image.
1104                 if (srcCompressed)
1105                 {
1106                         const deUint32  blockWidth      = getBlockWidth(m_params.src.image.format);
1107                         const deUint32  blockHeight     = getBlockHeight(m_params.src.image.format);
1108
1109                         imageCopy.srcOffset.x *= blockWidth;
1110                         imageCopy.srcOffset.y *= blockHeight;
1111                         imageCopy.extent.width *= blockWidth;
1112                         imageCopy.extent.height *= blockHeight;
1113                 }
1114
1115                 if (dstCompressed)
1116                 {
1117                         const deUint32  blockWidth      = getBlockWidth(m_params.dst.image.format);
1118                         const deUint32  blockHeight     = getBlockHeight(m_params.dst.image.format);
1119
1120                         imageCopy.dstOffset.x *= blockWidth;
1121                         imageCopy.dstOffset.y *= blockHeight;
1122                 }
1123
1124                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1125                 {
1126                         imageCopies.push_back(imageCopy);
1127                 }
1128                 else
1129                 {
1130                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1131                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1132                 }
1133         }
1134
1135         VkImageMemoryBarrier    imageBarriers[]         =
1136         {
1137                 // source image
1138                 {
1139                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1140                         DE_NULL,                                                                        // const void*                          pNext;
1141                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1142                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1143                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1144                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1145                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1146                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1147                         m_source.get(),                                                         // VkImage                                      image;
1148                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1149                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1150                                 0u,                                                             // deUint32                             baseMipLevel;
1151                                 1u,                                                             // deUint32                             mipLevels;
1152                                 0u,                                                             // deUint32                             baseArraySlice;
1153                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
1154                         }
1155                 },
1156                 // destination image
1157                 {
1158                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1159                         DE_NULL,                                                                        // const void*                          pNext;
1160                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1161                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1162                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1163                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1164                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1165                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1166                         m_destination.get(),                                            // VkImage                                      image;
1167                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1168                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1169                                 0u,                                                             // deUint32                             baseMipLevel;
1170                                 1u,                                                             // deUint32                             mipLevels;
1171                                 0u,                                                             // deUint32                             baseArraySlice;
1172                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
1173                         }
1174                 },
1175         };
1176
1177         beginCommandBuffer(vk, *m_cmdBuffer);
1178         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);
1179
1180         if (m_params.clearDestination)
1181         {
1182                 VkImageSubresourceRange range           = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1183                 VkClearColorValue               clearColor;
1184
1185                 clearColor.float32[0] = 1.0f;
1186                 clearColor.float32[1] = 1.0f;
1187                 clearColor.float32[2] = 1.0f;
1188                 clearColor.float32[3] = 1.0f;
1189                 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1190                 imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1191                 imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1192                 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);
1193         }
1194
1195         if (m_params.extensionUse == EXTENSION_USE_NONE)
1196         {
1197                 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());
1198         }
1199         else
1200         {
1201                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1202                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1203                 {
1204                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
1205                         DE_NULL,                                                                        // const void*                          pNext;
1206                         m_source.get(),                                                         // VkImage                                      srcImage;
1207                         m_params.src.image.operationLayout,                     // VkImageLayout                        srcImageLayout;
1208                         m_destination.get(),                                            // VkImage                                      dstImage;
1209                         m_params.dst.image.operationLayout,                     // VkImageLayout                        dstImageLayout;
1210                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
1211                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
1212                 };
1213
1214                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1215         }
1216
1217         endCommandBuffer(vk, *m_cmdBuffer);
1218
1219         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1220
1221         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
1222
1223         return checkTestResult(resultTextureLevel->getAccess());
1224 }
1225
1226 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1227 {
1228         const tcu::Vec4 fThreshold (0.0f);
1229         const tcu::UVec4 uThreshold (0u);
1230
1231         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1232         {
1233                 if (tcu::hasDepthComponent(result.getFormat().order))
1234                 {
1235                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1236                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1237                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1238
1239                         if (isFloatFormat(result.getFormat()))
1240                         {
1241                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1242                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1243                         }
1244                         else
1245                         {
1246                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1247                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1248                         }
1249                 }
1250
1251                 if (tcu::hasStencilComponent(result.getFormat().order))
1252                 {
1253                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1254                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1255                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1256
1257                         if (isFloatFormat(result.getFormat()))
1258                         {
1259                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1260                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1261                         }
1262                         else
1263                         {
1264                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1265                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1266                         }
1267                 }
1268         }
1269         else
1270         {
1271                 if (isFloatFormat(result.getFormat()))
1272                 {
1273                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1274                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1275                 }
1276                 else
1277                 {
1278                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1279                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1280                 }
1281         }
1282
1283         return tcu::TestStatus::pass("CopiesAndBlitting test");
1284 }
1285
1286 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1287 {
1288         DE_UNREF(mipLevel);
1289
1290         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1291         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1292         VkExtent3D      extent          = region.imageCopy.extent;
1293
1294         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1295         {
1296                 dstOffset.z = srcOffset.z;
1297                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1298         }
1299         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1300         {
1301                 srcOffset.z = dstOffset.z;
1302                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1303         }
1304
1305
1306         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1307         {
1308                 DE_ASSERT(src.getFormat() == dst.getFormat());
1309
1310                 // Copy depth.
1311                 if (tcu::hasDepthComponent(src.getFormat().order))
1312                 {
1313                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1314                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1315                         tcu::copy(dstSubRegion, srcSubRegion);
1316                 }
1317
1318                 // Copy stencil.
1319                 if (tcu::hasStencilComponent(src.getFormat().order))
1320                 {
1321                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1322                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1323                         tcu::copy(dstSubRegion, srcSubRegion);
1324                 }
1325         }
1326         else
1327         {
1328                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1329                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1330                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1331                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1332
1333                 tcu::copy(dstSubRegion, srcSubRegion);
1334         }
1335 }
1336
1337 class CopyImageToImageTestCase : public vkt::TestCase
1338 {
1339 public:
1340                                                         CopyImageToImageTestCase        (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 CopyImageToImage(context, m_params);
1351         }
1352
1353         virtual void                    checkSupport                            (Context&                                               context) const
1354         {
1355                 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1356                 {
1357                         if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1358                                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1359                 }
1360
1361                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1362                 {
1363                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1364                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1365                 }
1366
1367                 if (m_params.separateDepthStencilLayouts)
1368                         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1369                                 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1370
1371                 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1372                         (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1373                 {
1374                         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1375                                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1376                 }
1377
1378                 const VkPhysicalDeviceLimits    limits          = context.getDeviceProperties().limits;
1379                 VkImageFormatProperties                 properties;
1380
1381                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1382                                                                                                                                                                         m_params.src.image.format,
1383                                                                                                                                                                         m_params.src.image.imageType,
1384                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1385                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1386                                                                                                                                                                         0,
1387                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1388                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1389                                                                                                                                                                         m_params.dst.image.format,
1390                                                                                                                                                                         m_params.dst.image.imageType,
1391                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1392                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1393                                                                                                                                                                         0,
1394                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1395                 {
1396                         TCU_THROW(NotSupportedError, "Format not supported");
1397                 }
1398
1399                 // Check maxImageDimension1D
1400                 {
1401                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1402                                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1403
1404                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1405                                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1406                 }
1407
1408                 // Check maxImageDimension2D
1409                 {
1410                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1411                                 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1412                         {
1413                                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1414                         }
1415
1416                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1417                                 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1418                         {
1419                                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1420                         }
1421                 }
1422
1423                 // Check maxImageDimension3D
1424                 {
1425                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1426                                 || m_params.src.image.extent.height > limits.maxImageDimension3D
1427                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1428                         {
1429                                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1430                         }
1431
1432                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1433                                 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1434                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1435                         {
1436                                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1437                         }
1438                 }
1439         }
1440
1441 private:
1442         TestParams                              m_params;
1443 };
1444
1445 // Copy from buffer to buffer.
1446
1447 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1448 {
1449 public:
1450                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
1451         virtual tcu::TestStatus         iterate                                         (void);
1452 private:
1453         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1454         Move<VkBuffer>                          m_source;
1455         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1456         Move<VkBuffer>                          m_destination;
1457         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1458 };
1459
1460 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1461         : CopiesAndBlittingTestInstance (context, params)
1462 {
1463         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1464         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1465         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1466         const VkDevice                          vkDevice                        = context.getDevice();
1467         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1468         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1469
1470         // Create source buffer
1471         {
1472                 const VkBufferCreateInfo        sourceBufferParams              =
1473                 {
1474                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1475                         DE_NULL,                                                                        // const void*                  pNext;
1476                         0u,                                                                                     // VkBufferCreateFlags  flags;
1477                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
1478                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1479                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1480                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1481                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1482                 };
1483
1484                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1485                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1486                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1487         }
1488
1489         // Create destination buffer
1490         {
1491                 const VkBufferCreateInfo        destinationBufferParams =
1492                 {
1493                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1494                         DE_NULL,                                                                        // const void*                  pNext;
1495                         0u,                                                                                     // VkBufferCreateFlags  flags;
1496                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
1497                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1498                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1499                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1500                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1501                 };
1502
1503                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1504                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1505                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1506         }
1507 }
1508
1509 tcu::TestStatus CopyBufferToBuffer::iterate (void)
1510 {
1511         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
1512         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
1513         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
1514
1515         const int dstLevelWidth         = (int)(m_params.dst.buffer.size/4);
1516         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1517         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
1518
1519         generateExpectedResult();
1520
1521         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1522         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1523
1524         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1525         const VkDevice                          vkDevice        = m_context.getDevice();
1526         const VkQueue                           queue           = m_context.getUniversalQueue();
1527
1528         const VkBufferMemoryBarrier             srcBufferBarrier        =
1529         {
1530                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1531                 DE_NULL,                                                                        // const void*          pNext;
1532                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
1533                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
1534                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1535                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1536                 *m_source,                                                                      // VkBuffer                     buffer;
1537                 0u,                                                                                     // VkDeviceSize         offset;
1538                 m_params.src.buffer.size                                        // VkDeviceSize         size;
1539         };
1540
1541         const VkBufferMemoryBarrier             dstBufferBarrier        =
1542         {
1543                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1544                 DE_NULL,                                                                        // const void*          pNext;
1545                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1546                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1547                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1548                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1549                 *m_destination,                                                         // VkBuffer                     buffer;
1550                 0u,                                                                                     // VkDeviceSize         offset;
1551                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
1552         };
1553
1554         std::vector<VkBufferCopy>               bufferCopies;
1555         std::vector<VkBufferCopy2KHR>   bufferCopies2KHR;
1556         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1557         {
1558                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1559                 {
1560                         bufferCopies.push_back(m_params.regions[i].bufferCopy);
1561                 }
1562                 else
1563                 {
1564                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1565                         bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
1566                 }
1567         }
1568
1569         beginCommandBuffer(vk, *m_cmdBuffer);
1570         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);
1571
1572         if (m_params.extensionUse == EXTENSION_USE_NONE)
1573         {
1574                 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
1575         }
1576         else
1577         {
1578                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1579                 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
1580                 {
1581                         VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,       // VkStructureType                      sType;
1582                         DE_NULL,                                                                        // const void*                          pNext;
1583                         m_source.get(),                                                         // VkBuffer                                     srcBuffer;
1584                         m_destination.get(),                                            // VkBuffer                                     dstBuffer;
1585                         (deUint32)m_params.regions.size(),                      // uint32_t                                     regionCount;
1586                         &bufferCopies2KHR[0]                                            // const VkBufferCopy2KHR*      pRegions;
1587                 };
1588
1589                 vk.cmdCopyBuffer2KHR(*m_cmdBuffer, &copyBufferInfo2KHR);
1590         }
1591
1592         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);
1593         endCommandBuffer(vk, *m_cmdBuffer);
1594         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1595
1596         // Read buffer data
1597         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1598         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
1599         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1600
1601         return checkTestResult(resultLevel->getAccess());
1602 }
1603
1604 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1605 {
1606         DE_UNREF(mipLevel);
1607
1608         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
1609                          (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
1610                          (size_t)region.bufferCopy.size);
1611 }
1612
1613 class BufferToBufferTestCase : public vkt::TestCase
1614 {
1615 public:
1616                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
1617                                                                                                          const std::string&     name,
1618                                                                                                          const std::string&     description,
1619                                                                                                          const TestParams       params)
1620                                                                 : vkt::TestCase (testCtx, name, description)
1621                                                                 , m_params              (params)
1622                                                         {}
1623
1624         virtual TestInstance*   createInstance                  (Context& context) const
1625                                                         {
1626                                                                 return new CopyBufferToBuffer(context, m_params);
1627                                                         }
1628
1629         virtual void                    checkSupport(Context&   context) const
1630         {
1631                                                         if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1632                                                         {
1633                                                                 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1634                                                                 {
1635                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1636                                                                 }
1637                                                         }
1638         }
1639
1640         private:
1641         TestParams                              m_params;
1642 };
1643
1644 // Copy from image to buffer.
1645
1646 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1647 {
1648 public:
1649                                                                 CopyImageToBuffer                       (Context&       context,
1650                                                                                                                          TestParams     testParams);
1651         virtual tcu::TestStatus         iterate                                         (void);
1652 private:
1653         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1654
1655         tcu::TextureFormat                      m_textureFormat;
1656         VkDeviceSize                            m_bufferSize;
1657
1658         Move<VkImage>                           m_source;
1659         de::MovePtr<Allocation>         m_sourceImageAlloc;
1660         Move<VkBuffer>                          m_destination;
1661         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1662 };
1663
1664 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1665         : CopiesAndBlittingTestInstance(context, testParams)
1666         , m_textureFormat(mapVkFormat(testParams.src.image.format))
1667         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1668 {
1669         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1670         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1671         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1672         const VkDevice                          vkDevice                        = context.getDevice();
1673         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1674         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1675
1676         // Create source image
1677         {
1678                 const VkImageCreateInfo         sourceImageParams               =
1679                 {
1680                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1681                         DE_NULL,                                                                // const void*                  pNext;
1682                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1683                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1684                         m_params.src.image.format,                              // VkFormat                             format;
1685                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1686                         1u,                                                                             // deUint32                             mipLevels;
1687                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1688                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1689                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1690                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1691                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1692                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1693                         1u,                                                                             // deUint32                             queueFamilyCount;
1694                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1695                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1696                 };
1697
1698                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
1699                 m_sourceImageAlloc      = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1700                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1701         }
1702
1703         // Create destination buffer
1704         {
1705                 const VkBufferCreateInfo        destinationBufferParams =
1706                 {
1707                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1708                         DE_NULL,                                                                        // const void*                  pNext;
1709                         0u,                                                                                     // VkBufferCreateFlags  flags;
1710                         m_bufferSize,                                                           // VkDeviceSize                 size;
1711                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1712                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1713                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1714                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1715                 };
1716
1717                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1718                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1719                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1720         }
1721 }
1722
1723 tcu::TestStatus CopyImageToBuffer::iterate (void)
1724 {
1725         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1726                                                                                                                                                                 m_params.src.image.extent.width,
1727                                                                                                                                                                 m_params.src.image.extent.height,
1728                                                                                                                                                                 m_params.src.image.extent.depth));
1729         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1730         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1731         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1732
1733         generateExpectedResult();
1734
1735         uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
1736         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1737
1738         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1739         const VkDevice                          vkDevice        = m_context.getDevice();
1740         const VkQueue                           queue           = m_context.getUniversalQueue();
1741
1742         // Barriers for copying image to buffer
1743         const VkImageMemoryBarrier              imageBarrier            =
1744         {
1745                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1746                 DE_NULL,                                                                        // const void*                          pNext;
1747                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1748                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1749                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1750                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1751                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1752                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1753                 *m_source,                                                                      // VkImage                                      image;
1754                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1755                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
1756                         0u,                                                                     // deUint32                             baseMipLevel;
1757                         1u,                                                                     // deUint32                             mipLevels;
1758                         0u,                                                                     // deUint32                             baseArraySlice;
1759                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
1760                 }
1761         };
1762
1763         const VkBufferMemoryBarrier             bufferBarrier           =
1764         {
1765                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1766                 DE_NULL,                                                                        // const void*          pNext;
1767                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1768                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1769                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1770                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1771                 *m_destination,                                                         // VkBuffer                     buffer;
1772                 0u,                                                                                     // VkDeviceSize         offset;
1773                 m_bufferSize                                                            // VkDeviceSize         size;
1774         };
1775
1776         // Copy from image to buffer
1777         std::vector<VkBufferImageCopy>          bufferImageCopies;
1778         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
1779         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1780         {
1781                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1782                 {
1783                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1784                 }
1785                 else
1786                 {
1787                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1788                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
1789                 }
1790         }
1791
1792         beginCommandBuffer(vk, *m_cmdBuffer);
1793         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);
1794
1795         if (m_params.extensionUse == EXTENSION_USE_NONE)
1796         {
1797                 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
1798         }
1799         else
1800         {
1801                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1802                 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
1803                 {
1804                         VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,      // VkStructureType                              sType;
1805                         DE_NULL,                                                                                        // const void*                                  pNext;
1806                         m_source.get(),                                                                         // VkImage                                              srcImage;
1807                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                                srcImageLayout;
1808                         m_destination.get(),                                                            // VkBuffer                                             dstBuffer;
1809                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
1810                         &bufferImageCopies2KHR[0]                                                       // const VkBufferImageCopy2KHR* pRegions;
1811                 };
1812
1813                 vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
1814         }
1815
1816         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);
1817         endCommandBuffer(vk, *m_cmdBuffer);
1818
1819         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1820
1821         // Read buffer data
1822         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1823         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
1824         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1825
1826         return checkTestResult(resultLevel->getAccess());
1827 }
1828
1829 class CopyImageToBufferTestCase : public vkt::TestCase
1830 {
1831 public:
1832                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
1833                                                                                                                  const std::string&             name,
1834                                                                                                                  const std::string&             description,
1835                                                                                                                  const TestParams               params)
1836                                                                 : vkt::TestCase (testCtx, name, description)
1837                                                                 , m_params              (params)
1838                                                         {}
1839
1840         virtual TestInstance*   createInstance                          (Context&                               context) const
1841                                                         {
1842                                                                 return new CopyImageToBuffer(context, m_params);
1843                                                         }
1844
1845         virtual void                    checkSupport                            (Context&                               context) const
1846                                                         {
1847                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
1848                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
1849                                                                 {
1850                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1851                                                                 }
1852                                                         }
1853
1854 private:
1855         TestParams                              m_params;
1856 };
1857
1858 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1859 {
1860         DE_UNREF(mipLevel);
1861
1862         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
1863         if (!rowLength)
1864                 rowLength = region.bufferImageCopy.imageExtent.width;
1865
1866         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
1867         if (!imageHeight)
1868                 imageHeight = region.bufferImageCopy.imageExtent.height;
1869
1870         const int                       texelSize               = src.getFormat().getPixelSize();
1871         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
1872         const VkOffset3D        srcOffset               = region.bufferImageCopy.imageOffset;
1873         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
1874         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
1875
1876         for (deUint32 z = 0; z < extent.depth; z++)
1877         {
1878                 for (deUint32 y = 0; y < extent.height; y++)
1879                 {
1880                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
1881                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
1882                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1883                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1884                         tcu::copy(dstSubRegion, srcSubRegion);
1885                 }
1886         }
1887 }
1888
1889 // Copy from buffer to image.
1890
1891 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1892 {
1893 public:
1894                                                                 CopyBufferToImage                       (Context&       context,
1895                                                                                                                          TestParams     testParams);
1896         virtual tcu::TestStatus         iterate                                         (void);
1897
1898 private:
1899         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1900
1901         tcu::TextureFormat                      m_textureFormat;
1902         VkDeviceSize                            m_bufferSize;
1903
1904         Move<VkBuffer>                          m_source;
1905         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1906         Move<VkImage>                           m_destination;
1907         de::MovePtr<Allocation>         m_destinationImageAlloc;
1908 };
1909
1910 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1911         : CopiesAndBlittingTestInstance(context, testParams)
1912         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1913         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1914 {
1915         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1916         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1917         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1918         const VkDevice                          vkDevice                        = context.getDevice();
1919         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1920         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1921
1922         // Create source buffer
1923         {
1924                 const VkBufferCreateInfo        sourceBufferParams              =
1925                 {
1926                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1927                         DE_NULL,                                                                        // const void*                  pNext;
1928                         0u,                                                                                     // VkBufferCreateFlags  flags;
1929                         m_bufferSize,                                                           // VkDeviceSize                 size;
1930                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1931                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1932                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1933                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1934                 };
1935
1936                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1937                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1938                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1939         }
1940
1941         // Create destination image
1942         {
1943                 const VkImageCreateInfo         destinationImageParams  =
1944                 {
1945                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1946                         DE_NULL,                                                                // const void*                  pNext;
1947                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1948                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1949                         m_params.dst.image.format,                              // VkFormat                             format;
1950                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1951                         1u,                                                                             // deUint32                             mipLevels;
1952                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1953                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1954                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1955                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1956                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1957                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1958                         1u,                                                                             // deUint32                             queueFamilyCount;
1959                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1960                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1961                 };
1962
1963                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1964                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1965                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1966         }
1967 }
1968
1969 tcu::TestStatus CopyBufferToImage::iterate (void)
1970 {
1971         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1972         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
1973         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1974                                                                                                                                                                         m_params.dst.image.extent.width,
1975                                                                                                                                                                         m_params.dst.image.extent.height,
1976                                                                                                                                                                         m_params.dst.image.extent.depth));
1977
1978         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
1979
1980         generateExpectedResult();
1981
1982         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1983         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
1984
1985         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1986         const VkDevice                          vkDevice        = m_context.getDevice();
1987         const VkQueue                           queue           = m_context.getUniversalQueue();
1988
1989         const VkImageMemoryBarrier      imageBarrier    =
1990         {
1991                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1992                 DE_NULL,                                                                        // const void*                          pNext;
1993                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1994                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1995                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1996                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
1997                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1998                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1999                 *m_destination,                                                         // VkImage                                      image;
2000                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2001                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2002                         0u,                                                             // deUint32                             baseMipLevel;
2003                         1u,                                                             // deUint32                             mipLevels;
2004                         0u,                                                             // deUint32                             baseArraySlice;
2005                         getArraySize(m_params.dst.image)                                                                // deUint32                             arraySize;
2006                 }
2007         };
2008
2009         // Copy from buffer to image
2010         std::vector<VkBufferImageCopy>          bufferImageCopies;
2011         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2012         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2013         {
2014                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2015                 {
2016                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2017                 }
2018                 else
2019                 {
2020                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2021                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2022                 }
2023         }
2024
2025         beginCommandBuffer(vk, *m_cmdBuffer);
2026         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);
2027
2028         if (m_params.extensionUse == EXTENSION_USE_NONE)
2029         {
2030                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2031         }
2032         else
2033         {
2034                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2035                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2036                 {
2037                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2038                         DE_NULL,                                                                                        // const void*                                  pNext;
2039                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2040                         m_destination.get(),                                                            // VkImage                                              dstImage;
2041                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2042                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2043                         bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2044                 };
2045
2046                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2047         }
2048
2049
2050         endCommandBuffer(vk, *m_cmdBuffer);
2051
2052         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2053
2054         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
2055
2056         return checkTestResult(resultLevel->getAccess());
2057 }
2058
2059 class CopyBufferToImageTestCase : public vkt::TestCase
2060 {
2061 public:
2062                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
2063                                                                                                                  const std::string&             name,
2064                                                                                                                  const std::string&             description,
2065                                                                                                                  const TestParams               params)
2066                                                                 : vkt::TestCase (testCtx, name, description)
2067                                                                 , m_params              (params)
2068                                                         {}
2069
2070         virtual                                 ~CopyBufferToImageTestCase      (void) {}
2071
2072         virtual TestInstance*   createInstance                          (Context&                               context) const
2073                                                         {
2074                                                                 return new CopyBufferToImage(context, m_params);
2075                                                         }
2076
2077         virtual void                    checkSupport                            (Context&                               context) const
2078                                                         {
2079                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2080                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2081                                                                 {
2082                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2083                                                                 }
2084                                                         }
2085
2086
2087 private:
2088         TestParams                              m_params;
2089 };
2090
2091 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2092 {
2093         DE_UNREF(mipLevel);
2094
2095         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2096         if (!rowLength)
2097                 rowLength = region.bufferImageCopy.imageExtent.width;
2098
2099         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
2100         if (!imageHeight)
2101                 imageHeight = region.bufferImageCopy.imageExtent.height;
2102
2103         const int                       texelSize               = dst.getFormat().getPixelSize();
2104         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
2105         const VkOffset3D        dstOffset               = region.bufferImageCopy.imageOffset;
2106         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
2107         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2108
2109         for (deUint32 z = 0; z < extent.depth; z++)
2110         {
2111                 for (deUint32 y = 0; y < extent.height; y++)
2112                 {
2113                         int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2114                         const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2115                         const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2116                                                                                                                                                   region.bufferImageCopy.imageExtent.width, 1, 1);
2117                         tcu::copy(dstSubRegion, srcSubRegion);
2118                 }
2119         }
2120 }
2121
2122 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2123 {
2124 public:
2125                                                                 CopyBufferToDepthStencil        (Context& context,
2126                                                                                                                          TestParams     testParams);
2127         virtual tcu::TestStatus         iterate                                         (void);
2128 private:
2129         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2130
2131         tcu::TextureFormat                      m_textureFormat;
2132         VkDeviceSize                            m_bufferSize;
2133
2134         Move<VkBuffer>                          m_source;
2135         de::MovePtr<Allocation>         m_sourceBufferAlloc;
2136         Move<VkImage>                           m_destination;
2137         de::MovePtr<Allocation>         m_destinationImageAlloc;
2138 };
2139
2140 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2141 {
2142         DE_UNREF(mipLevel);
2143
2144         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2145         if (!rowLength)
2146                 rowLength = region.bufferImageCopy.imageExtent.width;
2147
2148         deUint32                        imageHeight = region.bufferImageCopy.bufferImageHeight;
2149         if (!imageHeight)
2150                 imageHeight = region.bufferImageCopy.imageExtent.height;
2151
2152         const int                       texelSize       = dst.getFormat().getPixelSize();
2153         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
2154         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
2155         const int                       texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2156
2157         for (deUint32 z = 0; z < extent.depth; z++)
2158         {
2159                 for (deUint32 y = 0; y < extent.height; y++)
2160                 {
2161                         int                                                                     texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2162                         const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2163                         const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2164                                 region.bufferImageCopy.imageExtent.width, 1, 1);
2165
2166                         if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2167                         {
2168                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2169                         }
2170                         else
2171                         {
2172                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2173                         }
2174                 }
2175         }
2176 }
2177
2178 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2179 {
2180         VkFormatProperties formatProps;
2181         vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2182         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2183 }
2184
2185 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2186         : CopiesAndBlittingTestInstance(context, testParams)
2187         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2188         , m_bufferSize(0)
2189 {
2190         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2191         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2192         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2193         const VkDevice                          vkDevice                        = context.getDevice();
2194         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2195         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2196         const bool                                      hasDepth                        = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2197         const bool                                      hasStencil                      = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2198
2199         if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2200         {
2201                 TCU_THROW(NotSupportedError, "Image format not supported.");
2202         }
2203
2204         if (hasDepth)
2205         {
2206                 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2207                 if (texelSize > sizeof(float))
2208                 {
2209                         // We must have D32F_S8 format, depth must be packed so we only need
2210                         // to allocate space for the D32F part. Stencil will be separate
2211                         texelSize = sizeof(float);
2212                 }
2213                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2214         }
2215         if (hasStencil)
2216         {
2217                 // Stencil is always 8bits and packed.
2218                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2219         }
2220
2221         // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2222         {
2223                 const VkBufferCreateInfo        sourceBufferParams              =
2224                 {
2225                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2226                         DE_NULL,                                                                        // const void*                  pNext;
2227                         0u,                                                                                     // VkBufferCreateFlags  flags;
2228                         m_bufferSize,                                                           // VkDeviceSize                 size;
2229                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
2230                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2231                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2232                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2233                 };
2234
2235                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
2236                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2237                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2238         }
2239
2240         // Create destination image
2241         {
2242                 const VkImageCreateInfo         destinationImageParams  =
2243                 {
2244                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2245                         DE_NULL,                                                                // const void*                  pNext;
2246                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2247                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2248                         m_params.dst.image.format,                              // VkFormat                             format;
2249                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2250                         1u,                                                                             // deUint32                             mipLevels;
2251                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2252                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2253                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2254                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2255                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2256                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2257                         1u,                                                                             // deUint32                             queueFamilyCount;
2258                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2259                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2260                 };
2261
2262                 m_destination                           = createImage(vk, vkDevice, &destinationImageParams);
2263                 m_destinationImageAlloc         = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2264                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2265         }
2266 }
2267
2268 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2269 {
2270         // Create source depth/stencil content. Treat as 1D texture to get different pattern
2271         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2272         // Fill buffer with linear gradiant
2273         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2274
2275         // Create image layer for depth/stencil
2276         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2277                 m_params.dst.image.extent.width,
2278                 m_params.dst.image.extent.height,
2279                 m_params.dst.image.extent.depth));
2280
2281         // Fill image layer with 2D gradiant
2282         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2283
2284         // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2285         // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2286         // This emulates what the HW will be doing.
2287         generateExpectedResult();
2288
2289         // Upload our source depth/stencil content to the source buffer
2290         // This is the buffer that will be used by region commands
2291         std::vector<VkBufferImageCopy>          bufferImageCopies;
2292         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2293         VkDeviceSize                                    bufferOffset    = 0;
2294         const VkDevice                                  vkDevice                = m_context.getDevice();
2295         const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
2296         const VkQueue                                   queue                   = m_context.getUniversalQueue();
2297         char*                                                   dstPtr                  = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2298         bool                                                    depthLoaded             = DE_FALSE;
2299         bool                                                    stencilLoaded   = DE_FALSE;
2300         VkDeviceSize                                    depthOffset             = 0;
2301         VkDeviceSize                                    stencilOffset   = 0;
2302
2303         // To be able to test ordering depth & stencil differently
2304         // we take the given copy regions and use that as the desired order
2305         // and copy the appropriate data into place and compute the appropriate
2306         // data offsets to be used in the copy command.
2307         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2308         {
2309                 tcu::ConstPixelBufferAccess bufferAccess        = m_sourceTextureLevel->getAccess();
2310                 deUint32                                        bufferSize              = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2311                 VkBufferImageCopy                       copyData                = m_params.regions[i].bufferImageCopy;
2312                 char*                                           srcPtr;
2313
2314                 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2315                 {
2316                         // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2317                         tcu::TextureLevel       depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2318                         bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2319                         // Copy depth component only from source data. This gives us packed depth-only data.
2320                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2321                         srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2322                         // Copy packed depth-only data to output buffer
2323                         deMemcpy(dstPtr, srcPtr, bufferSize);
2324                         depthLoaded = DE_TRUE;
2325                         depthOffset = bufferOffset;
2326                         dstPtr += bufferSize;
2327                         bufferOffset += bufferSize;
2328                         copyData.bufferOffset += depthOffset;
2329                 }
2330                 else if (!stencilLoaded)
2331                 {
2332                         // Create level that is same component as stencil buffer (always 8-bits)
2333                         tcu::TextureLevel       stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2334                         // Copy stencil component only from source data. This gives us packed stencil-only data.
2335                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2336                         srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2337                         // Copy packed stencil-only data to output buffer
2338                         deMemcpy(dstPtr, srcPtr, bufferSize);
2339                         stencilLoaded = DE_TRUE;
2340                         stencilOffset = bufferOffset;
2341                         dstPtr += bufferSize;
2342                         bufferOffset += bufferSize;
2343
2344                         // Reference image generation uses pixel offsets based on buffer offset.
2345                         // We need to adjust the offset now that the stencil data is not interleaved.
2346                         copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2347
2348                         copyData.bufferOffset += stencilOffset;
2349                 }
2350
2351                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2352                 {
2353                         bufferImageCopies.push_back(copyData);
2354                 }
2355                 else
2356                 {
2357                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2358                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2359                 }
2360         }
2361
2362         flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2363
2364         // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2365         // depth and stencil to known values.
2366         // Uses uploadImageAspect so makes its own buffers for depth and stencil
2367         // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2368         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2369
2370         const VkImageMemoryBarrier      imageBarrier    =
2371         {
2372                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2373                 DE_NULL,                                                                        // const void*                          pNext;
2374                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2375                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2376                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2377                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2378                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2379                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2380                 *m_destination,                                                         // VkImage                                      image;
2381                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2382                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2383                         0u,                                                             // deUint32                             baseMipLevel;
2384                         1u,                                                             // deUint32                             mipLevels;
2385                         0u,                                                             // deUint32                             baseArraySlice;
2386                         1u                                                              // deUint32                             arraySize;
2387                 }
2388         };
2389
2390         // Copy from buffer to depth/stencil image
2391
2392         beginCommandBuffer(vk, *m_cmdBuffer);
2393         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);
2394
2395         if (m_params.extensionUse == EXTENSION_USE_NONE)
2396         {
2397                 if (m_params.singleCommand)
2398                 {
2399                         // Issue a single copy command with regions defined by the test.
2400                         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2401                 }
2402                 else
2403                 {
2404                         // Issue a a copy command per region defined by the test.
2405                         for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2406                         {
2407                                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2408                         }
2409                 }
2410         }
2411         else
2412         {
2413                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2414
2415                 if (m_params.singleCommand)
2416                 {
2417                         // Issue a single copy command with regions defined by the test.
2418                         const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2419                         {
2420                                 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2421                                 DE_NULL,                                                                                        // const void*                                  pNext;
2422                                 m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2423                                 m_destination.get(),                                                            // VkImage                                              dstImage;
2424                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2425                                 (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2426                                 bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2427                         };
2428                         vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2429                 }
2430                 else
2431                 {
2432                         // Issue a a copy command per region defined by the test.
2433                         for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2434                         {
2435                                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2436                                 {
2437                                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2438                                         DE_NULL,                                                                                        // const void*                                  pNext;
2439                                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2440                                         m_destination.get(),                                                            // VkImage                                              dstImage;
2441                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2442                                         1,                                                                                                      // uint32_t                                             regionCount;
2443                                         &bufferImageCopies2KHR[i]                                                       // const VkBufferImageCopy2KHR* pRegions;
2444                                 };
2445                                 // Issue a single copy command with regions defined by the test.
2446                                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2447                         }
2448                 }
2449         }
2450         endCommandBuffer(vk, *m_cmdBuffer);
2451
2452         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2453
2454         de::MovePtr<tcu::TextureLevel>  resultLevel = readImage(*m_destination, m_params.dst.image);
2455
2456         // For combined depth/stencil formats both aspects are checked even when the test only
2457         // copies one. Clear such aspects here for both the result and the reference.
2458         if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2459         {
2460                 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2461                 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2462         }
2463         if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2464         {
2465                 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2466                 tcu::clearStencil(resultLevel->getAccess(), 0);
2467         }
2468
2469         return checkTestResult(resultLevel->getAccess());
2470 }
2471
2472 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
2473 {
2474 public:
2475                                                         CopyBufferToDepthStencilTestCase        (tcu::TestContext&              testCtx,
2476                                                                                                                                  const std::string&             name,
2477                                                                                                                                  const std::string&             description,
2478                                                                                                                                  const TestParams               params)
2479                                                                 : vkt::TestCase(testCtx, name, description)
2480                                                                 , m_params(params)
2481                                                         {}
2482
2483         virtual                                 ~CopyBufferToDepthStencilTestCase       (void) {}
2484
2485         virtual TestInstance*   createInstance                                          (Context&                               context) const
2486                                                         {
2487                                                                 return new CopyBufferToDepthStencil(context, m_params);
2488                                                         }
2489
2490         virtual void                    checkSupport                                            (Context&                               context) const
2491                                                         {
2492                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2493                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2494                                                                 {
2495                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2496                                                                 }
2497                                                         }
2498
2499 private:
2500         TestParams                              m_params;
2501 };
2502
2503 // Copy from image to image with scaling.
2504
2505 class BlittingImages : public CopiesAndBlittingTestInstance
2506 {
2507 public:
2508                                                                                 BlittingImages                                  (Context&       context,
2509                                                                                                                                                  TestParams params);
2510         virtual tcu::TestStatus                         iterate                                                 (void);
2511 protected:
2512         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result);
2513         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2514         virtual void                                            generateExpectedResult                  (void);
2515 private:
2516         bool                                                            checkNonNearestFilteredResult   (const tcu::ConstPixelBufferAccess&     result,
2517                                                                                                                                                  const tcu::ConstPixelBufferAccess&     clampedReference,
2518                                                                                                                                                  const tcu::ConstPixelBufferAccess&     unclampedReference,
2519                                                                                                                                                  const tcu::TextureFormat&                      sourceFormat);
2520         bool                                                            checkNearestFilteredResult              (const tcu::ConstPixelBufferAccess&     result,
2521                                                                                                                                                  const tcu::ConstPixelBufferAccess& source);
2522
2523         Move<VkImage>                                           m_source;
2524         de::MovePtr<Allocation>                         m_sourceImageAlloc;
2525         Move<VkImage>                                           m_destination;
2526         de::MovePtr<Allocation>                         m_destinationImageAlloc;
2527
2528         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel;
2529 };
2530
2531 BlittingImages::BlittingImages (Context& context, TestParams params)
2532         : CopiesAndBlittingTestInstance(context, params)
2533 {
2534         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2535         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2536         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2537         const VkDevice                          vkDevice                        = context.getDevice();
2538         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2539         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2540
2541         // Create source image
2542         {
2543                 const VkImageCreateInfo         sourceImageParams               =
2544                 {
2545                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2546                         DE_NULL,                                                                // const void*                  pNext;
2547                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
2548                         m_params.src.image.imageType,                   // VkImageType                  imageType;
2549                         m_params.src.image.format,                              // VkFormat                             format;
2550                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
2551                         1u,                                                                             // deUint32                             mipLevels;
2552                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
2553                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2554                         m_params.src.image.tiling,                              // VkImageTiling                tiling;
2555                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2556                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2557                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2558                         1u,                                                                             // deUint32                             queueFamilyCount;
2559                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2560                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2561                 };
2562
2563                 m_source = createImage(vk, vkDevice, &sourceImageParams);
2564                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2565                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2566         }
2567
2568         // Create destination image
2569         {
2570                 const VkImageCreateInfo         destinationImageParams  =
2571                 {
2572                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2573                         DE_NULL,                                                                // const void*                  pNext;
2574                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2575                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2576                         m_params.dst.image.format,                              // VkFormat                             format;
2577                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2578                         1u,                                                                             // deUint32                             mipLevels;
2579                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2580                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2581                         m_params.dst.image.tiling,                              // VkImageTiling                tiling;
2582                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2583                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2584                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2585                         1u,                                                                             // deUint32                             queueFamilyCount;
2586                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2587                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2588                 };
2589
2590                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2591                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2592                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2593         }
2594 }
2595
2596 tcu::TestStatus BlittingImages::iterate (void)
2597 {
2598         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
2599         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
2600         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
2601                                                                                                                                                                 m_params.src.image.extent.width,
2602                                                                                                                                                                 m_params.src.image.extent.height,
2603                                                                                                                                                                 m_params.src.image.extent.depth));
2604         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
2605         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
2606                                                                                                                                                                          (int)m_params.dst.image.extent.width,
2607                                                                                                                                                                          (int)m_params.dst.image.extent.height,
2608                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
2609         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
2610         generateExpectedResult();
2611
2612         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
2613         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
2614
2615         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
2616         const VkDevice                          vkDevice                        = m_context.getDevice();
2617         const VkQueue                           queue                           = m_context.getUniversalQueue();
2618
2619         std::vector<VkImageBlit>                regions;
2620         std::vector<VkImageBlit2KHR>    regions2KHR;
2621         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2622         {
2623                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2624                 {
2625                         regions.push_back(m_params.regions[i].imageBlit);
2626                 }
2627                 else
2628                 {
2629                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2630                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
2631                 }
2632         }
2633
2634         // Barriers for copying image to buffer
2635         const VkImageMemoryBarrier              srcImageBarrier         =
2636         {
2637                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2638                 DE_NULL,                                                                        // const void*                          pNext;
2639                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2640                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
2641                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2642                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
2643                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2644                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2645                 m_source.get(),                                                         // VkImage                                      image;
2646                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2647                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
2648                         0u,                                                             // deUint32                             baseMipLevel;
2649                         1u,                                                             // deUint32                             mipLevels;
2650                         0u,                                                             // deUint32                             baseArraySlice;
2651                         1u                                                              // deUint32                             arraySize;
2652                 }
2653         };
2654
2655         const VkImageMemoryBarrier              dstImageBarrier         =
2656         {
2657                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2658                 DE_NULL,                                                                        // const void*                          pNext;
2659                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2660                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2661                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2662                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
2663                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2664                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2665                 m_destination.get(),                                            // VkImage                                      image;
2666                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2667                         getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
2668                         0u,                                                             // deUint32                             baseMipLevel;
2669                         1u,                                                             // deUint32                             mipLevels;
2670                         0u,                                                             // deUint32                             baseArraySlice;
2671                         1u                                                              // deUint32                             arraySize;
2672                 }
2673         };
2674
2675         beginCommandBuffer(vk, *m_cmdBuffer);
2676         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);
2677         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);
2678
2679         if (m_params.extensionUse == EXTENSION_USE_NONE)
2680         {
2681                 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);
2682         }
2683         else
2684         {
2685                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2686                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
2687                 {
2688                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
2689                         DE_NULL,                                                                        // const void*                                  pNext;
2690                         m_source.get(),                                                         // VkImage                                              srcImage;
2691                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
2692                         m_destination.get(),                                            // VkImage                                              dstImage;
2693                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
2694                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
2695                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
2696                         m_params.filter,                                                        // VkFilter                                             filter;
2697                 };
2698                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
2699         }
2700
2701         endCommandBuffer(vk, *m_cmdBuffer);
2702         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2703
2704         de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
2705
2706         return checkTestResult(resultTextureLevel->getAccess());
2707 }
2708
2709 static float calculateFloatConversionError (int srcBits)
2710 {
2711         if (srcBits > 0)
2712         {
2713                 const int       clampedBits     = de::clamp<int>(srcBits, 0, 32);
2714                 const float     srcMaxValue     = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
2715                 const float     error           = 1.0f / srcMaxValue;
2716
2717                 return de::clamp<float>(error, 0.0f, 1.0f);
2718         }
2719         else
2720                 return 1.0f;
2721 }
2722
2723 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
2724 {
2725         tcu::Vec4 threshold(0.01f);
2726
2727         switch (format.type)
2728         {
2729         case tcu::TextureFormat::HALF_FLOAT:
2730                 threshold = tcu::Vec4(0.005f);
2731                 break;
2732
2733         case tcu::TextureFormat::FLOAT:
2734         case tcu::TextureFormat::FLOAT64:
2735                 threshold = tcu::Vec4(0.001f);
2736                 break;
2737
2738         case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
2739                 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
2740                 break;
2741
2742         case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
2743                 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
2744                 break;
2745
2746         case tcu::TextureFormat::UNORM_INT_1010102_REV:
2747                 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
2748                 break;
2749
2750         case tcu:: TextureFormat::UNORM_INT8:
2751                 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
2752                 break;
2753
2754         default:
2755                 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
2756                 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
2757                                       calculateFloatConversionError(bits.y()),
2758                                       calculateFloatConversionError(bits.z()),
2759                                       calculateFloatConversionError(bits.w()));
2760         }
2761
2762         // Return value matching the channel order specified by the format
2763         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
2764                 return threshold.swizzle(2, 1, 0, 3);
2765         else
2766                 return threshold;
2767 }
2768
2769 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&  result,
2770                                                                                                         const tcu::ConstPixelBufferAccess&      clampedExpected,
2771                                                                                                         const tcu::ConstPixelBufferAccess&      unclampedExpected,
2772                                                                                                         const tcu::TextureFormat&                       srcFormat)
2773 {
2774         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
2775         const tcu::TextureFormat                dstFormat               = result.getFormat();
2776         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
2777         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
2778         bool                                                    isOk                    = false;
2779
2780         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
2781
2782         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
2783         // the other must also store values a signed/unsigned integer
2784         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
2785         // despite the fact that both formats are sampled as floats
2786         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
2787                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
2788         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
2789                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
2790         if (dstImageIsIntClass != srcImageIsIntClass)
2791         {
2792                 log << tcu::TestLog::EndSection;
2793                 return false;
2794         }
2795
2796         if (isFloatFormat(dstFormat))
2797         {
2798                 const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
2799                 const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
2800                 const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
2801                 const tcu::Vec4 threshold       = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
2802
2803                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2804                 log << tcu::TestLog::EndSection;
2805
2806                 if (!isOk)
2807                 {
2808                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
2809                         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2810                         log << tcu::TestLog::EndSection;
2811                 }
2812         }
2813         else
2814         {
2815                 tcu::UVec4      threshold;
2816                 // Calculate threshold depending on channel width of destination format.
2817                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
2818                 const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
2819                 for (deUint32 i = 0; i < 4; ++i)
2820                         threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
2821
2822                 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2823                 log << tcu::TestLog::EndSection;
2824
2825                 if (!isOk)
2826                 {
2827                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
2828                         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2829                         log << tcu::TestLog::EndSection;
2830                 }
2831         }
2832
2833         return isOk;
2834 }
2835
2836 //! Utility to encapsulate coordinate computation and loops.
2837 struct CompareEachPixelInEachRegion
2838 {
2839         virtual          ~CompareEachPixelInEachRegion  (void) {}
2840         virtual bool compare                                                            (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
2841
2842         bool forEach (const void*                                                       pUserData,
2843                                   const std::vector<CopyRegion>&                regions,
2844                                   const int                                                             sourceWidth,
2845                                   const int                                                             sourceHeight,
2846                                   const int                                                             sourceDepth,
2847                                   const tcu::PixelBufferAccess&                 errorMask) const
2848         {
2849                 bool compareOk = true;
2850
2851                 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
2852                 {
2853                         const VkImageBlit& blit = regionIter->imageBlit;
2854
2855                         const int       xStart  = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
2856                         const int       yStart  = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
2857                         const int       zStart  = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
2858                         const int       xEnd    = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
2859                         const int       yEnd    = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
2860                         const int       zEnd    = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
2861                         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);
2862                         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);
2863                         const float     zScale  = static_cast<float>(blit.srcOffsets[1].z - blit.srcOffsets[0].z) / static_cast<float>(blit.dstOffsets[1].z - blit.dstOffsets[0].z);
2864                         const float srcInvW     = 1.0f / static_cast<float>(sourceWidth);
2865                         const float srcInvH     = 1.0f / static_cast<float>(sourceHeight);
2866                         const float srcInvD     = 1.0f / static_cast<float>(sourceDepth);
2867
2868                         for (int z = zStart; z < zEnd; z++)
2869                         for (int y = yStart; y < yEnd; y++)
2870                         for (int x = xStart; x < xEnd; x++)
2871                         {
2872                                 const tcu::Vec3 srcNormCoord
2873                                 (
2874                                         (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
2875                                         (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
2876                                         (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
2877                                 );
2878
2879                                 if (!compare(pUserData, x, y, z, srcNormCoord))
2880                                 {
2881                                         errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
2882                                         compareOk = false;
2883                                 }
2884                         }
2885                 }
2886                 return compareOk;
2887         }
2888 };
2889
2890 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
2891 {
2892         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
2893         const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
2894
2895         if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
2896         {
2897                 return getFormatThreshold(format);
2898         }
2899         else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
2900                          channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
2901         {
2902                 const bool      isSigned        = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
2903                 const float     range           = isSigned ? 1.0f - (-1.0f)
2904                                                                                    : 1.0f -   0.0f;
2905
2906                 tcu::Vec4 v;
2907                 for (int i = 0; i < 4; ++i)
2908                 {
2909                         if (bitDepth[i] == 0)
2910                                 v[i] = 1.0f;
2911                         else
2912                                 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
2913                 }
2914                 return v;
2915         }
2916         else
2917         {
2918                 DE_ASSERT(0);
2919                 return tcu::Vec4();
2920         }
2921 }
2922
2923 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&        source,
2924                                                           const tcu::ConstPixelBufferAccess&    result,
2925                                                           const tcu::PixelBufferAccess&                 errorMask,
2926                                                           const std::vector<CopyRegion>&                regions)
2927 {
2928         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);
2929         tcu::LookupPrecision    precision;
2930
2931         {
2932                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
2933                 const tcu::Vec4         srcMaxDiff      = getFloatOrFixedPointFormatThreshold(source.getFormat());
2934                 const tcu::Vec4         dstMaxDiff      = getFloatOrFixedPointFormatThreshold(result.getFormat());
2935
2936                 precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
2937                 precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
2938         }
2939
2940         const struct Capture
2941         {
2942                 const tcu::ConstPixelBufferAccess&      source;
2943                 const tcu::ConstPixelBufferAccess&      result;
2944                 const tcu::Sampler&                                     sampler;
2945                 const tcu::LookupPrecision&                     precision;
2946                 const bool                                                      isSRGB;
2947         } capture =
2948         {
2949                 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
2950         };
2951
2952         const struct Loop : CompareEachPixelInEachRegion
2953         {
2954                 Loop (void) {}
2955
2956                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
2957                 {
2958                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
2959                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
2960                         tcu::Vec4                                               dstColor                        = c.result.getPixel(x, y, z);
2961
2962                         // TexLookupVerifier performs a conversion to linear space, so we have to as well
2963                         if (c.isSRGB)
2964                                 dstColor = tcu::sRGBToLinear(dstColor);
2965
2966                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
2967                 }
2968         } loop;
2969
2970         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
2971 }
2972
2973 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&  source,
2974                                                         const tcu::ConstPixelBufferAccess&      result,
2975                                                         const tcu::PixelBufferAccess&           errorMask,
2976                                                         const std::vector<CopyRegion>&          regions)
2977 {
2978         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);
2979         tcu::IntLookupPrecision precision;
2980
2981         {
2982                 const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
2983                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
2984
2985                 for (deUint32 i = 0; i < 4; ++i) {
2986                         precision.colorThreshold[i]     = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
2987                         precision.colorMask[i]          = dstBitDepth[i] != 0;
2988                 }
2989         }
2990
2991         // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
2992         // does the conversion on the fly without wasting memory, but this approach is more straightforward.
2993         tcu::TextureLevel                               convertedSourceTexture  (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
2994         const tcu::PixelBufferAccess    convertedSource                 = convertedSourceTexture.getAccess();
2995
2996         for (int z = 0; z < source.getDepth();  ++z)
2997         for (int y = 0; y < source.getHeight(); ++y)
2998         for (int x = 0; x < source.getWidth();  ++x)
2999                 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3000
3001         const struct Capture
3002         {
3003                 const tcu::ConstPixelBufferAccess&      source;
3004                 const tcu::ConstPixelBufferAccess&      result;
3005                 const tcu::Sampler&                                     sampler;
3006                 const tcu::IntLookupPrecision&          precision;
3007         } capture =
3008         {
3009                 convertedSource, result, sampler, precision
3010         };
3011
3012         const struct Loop : CompareEachPixelInEachRegion
3013         {
3014                 Loop (void) {}
3015
3016                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3017                 {
3018                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
3019                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
3020                         const tcu::IVec4                                dstColor                        = c.result.getPixelInt(x, y, z);
3021
3022                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3023                 }
3024         } loop;
3025
3026         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3027 }
3028
3029 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
3030                                                                                                  const tcu::ConstPixelBufferAccess& source)
3031 {
3032         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
3033         const tcu::TextureFormat                dstFormat               = result.getFormat();
3034         const tcu::TextureFormat                srcFormat               = source.getFormat();
3035         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3036         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3037
3038         tcu::TextureLevel               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3039         tcu::PixelBufferAccess  errorMask                       = errorMaskStorage.getAccess();
3040         tcu::Vec4                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3041         tcu::Vec4                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3042         bool                                    ok                                      = false;
3043
3044         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3045
3046         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3047         // the other must also store values a signed/unsigned integer
3048         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3049         // despite the fact that both formats are sampled as floats
3050         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3051                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3052         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3053                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3054         if (dstImageIsIntClass != srcImageIsIntClass)
3055                 return false;
3056
3057         if (dstImageIsIntClass)
3058         {
3059                 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3060         }
3061         else
3062                 ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);
3063
3064         if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3065                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3066
3067         if (!ok)
3068         {
3069                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3070                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3071                         << tcu::TestLog::Image("ErrorMask",     "Error mask", errorMask)
3072                         << tcu::TestLog::EndImageSet;
3073         }
3074         else
3075         {
3076                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3077                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3078                         << tcu::TestLog::EndImageSet;
3079         }
3080
3081         return ok;
3082 }
3083
3084 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
3085 {
3086         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
3087         const std::string failMessage("Result image is incorrect");
3088
3089         if (m_params.filter != VK_FILTER_NEAREST)
3090         {
3091                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
3092                 {
3093                         if (tcu::hasDepthComponent(result.getFormat().order))
3094                         {
3095                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
3096                                 const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
3097                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
3098                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
3099                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
3100
3101                                 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
3102                                         return tcu::TestStatus::fail(failMessage);
3103                         }
3104
3105                         if (tcu::hasStencilComponent(result.getFormat().order))
3106                         {
3107                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
3108                                 const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
3109                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
3110                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
3111                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
3112
3113                                 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
3114                                         return tcu::TestStatus::fail(failMessage);
3115                         }
3116                 }
3117                 else
3118                 {
3119                         const tcu::TextureFormat        sourceFormat    = mapVkFormat(m_params.src.image.format);
3120
3121                         if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
3122                                 return tcu::TestStatus::fail(failMessage);
3123                 }
3124         }
3125         else // NEAREST filtering
3126         {
3127                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
3128                 {
3129                         if (tcu::hasDepthComponent(result.getFormat().order))
3130                         {
3131                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_DEPTH;
3132                                 const tcu::ConstPixelBufferAccess               depthResult             = tcu::getEffectiveDepthStencilAccess(result, mode);
3133                                 const tcu::ConstPixelBufferAccess               depthSource             = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
3134
3135                                 if (!checkNearestFilteredResult(depthResult, depthSource))
3136                                         return tcu::TestStatus::fail(failMessage);
3137                         }
3138
3139                         if (tcu::hasStencilComponent(result.getFormat().order))
3140                         {
3141                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_STENCIL;
3142                                 const tcu::ConstPixelBufferAccess               stencilResult   = tcu::getEffectiveDepthStencilAccess(result, mode);
3143                                 const tcu::ConstPixelBufferAccess               stencilSource   = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
3144
3145                                 if (!checkNearestFilteredResult(stencilResult, stencilSource))
3146                                         return tcu::TestStatus::fail(failMessage);
3147                         }
3148                 }
3149                 else
3150                 {
3151                         if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
3152                                 return tcu::TestStatus::fail(failMessage);
3153                 }
3154         }
3155
3156         return tcu::TestStatus::pass("Pass");
3157 }
3158
3159 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
3160 {
3161         return isSRGB(format) ? linearToSRGB(color) : color;
3162 }
3163
3164 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
3165 {
3166         DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
3167
3168         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
3169                                         filter, filter, 0.0f, false);
3170
3171         float sX = (float)regionExtent.x / (float)dst.getWidth();
3172         float sY = (float)regionExtent.y / (float)dst.getHeight();
3173         float sZ = (float)regionExtent.z / (float)dst.getDepth();
3174
3175         for (int z = 0; z < dst.getDepth(); z++)
3176         for (int y = 0; y < dst.getHeight(); y++)
3177         for (int x = 0; x < dst.getWidth(); x++)
3178         {
3179                 float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
3180                 float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
3181                 float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ? (float)regionExtent.z + (float)regionOffset.z - ((float)z+0.5f)*sZ : (float)regionOffset.z + ((float)z+0.5f)*sZ;
3182                 if (dst.getDepth() > 1)
3183                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
3184                 else
3185                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
3186         }
3187 }
3188
3189 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
3190 {
3191         DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
3192
3193         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
3194                         filter, filter, 0.0f, false);
3195
3196         const float sX = (float)src.getWidth() / (float)dst.getWidth();
3197         const float sY = (float)src.getHeight() / (float)dst.getHeight();
3198         const float sZ = (float)src.getDepth() / (float)dst.getDepth();
3199
3200         const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
3201         const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
3202         const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
3203
3204         const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
3205         const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
3206         const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
3207
3208         for (int z = 0; z < dst.getDepth(); ++z)
3209         for (int y = 0; y < dst.getHeight(); ++y)
3210         for (int x = 0; x < dst.getWidth(); ++x)
3211         {
3212                 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX, ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)), x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
3213         }
3214 }
3215
3216 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
3217 {
3218         const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
3219         const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
3220         const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
3221         const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
3222
3223         if (mirrorMode != 0u)
3224         {
3225                 //sourceRegion
3226                 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
3227                 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
3228                 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
3229
3230                 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
3231                 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
3232                 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
3233
3234                 //destinationRegion
3235                 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
3236                 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
3237                 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
3238
3239                 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
3240                 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
3241                 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
3242         }
3243 }
3244
3245 // Mirror X, Y and Z as required by the offset values in the 3 axes.
3246 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
3247 {
3248         MirrorMode mode = 0u;
3249
3250         if (from.x > to.x)
3251                 mode |= MIRROR_MODE_X;
3252
3253         if (from.y > to.y)
3254                 mode |= MIRROR_MODE_Y;
3255
3256         if (from.z > to.z)
3257                 mode |= MIRROR_MODE_Z;
3258
3259         return mode;
3260 }
3261
3262 // Mirror the axes that are mirrored either in the source or destination, but not both.
3263 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
3264 {
3265         static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
3266
3267         const MirrorMode source          = getMirrorMode(s1, s2);
3268         const MirrorMode destination = getMirrorMode(d1, d2);
3269
3270         MirrorMode mode = 0u;
3271
3272         for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
3273         {
3274                 const MirrorModeBits bit = kBits[i];
3275                 if ((source & bit) != (destination & bit))
3276                         mode |= bit;
3277         }
3278
3279         return mode;
3280 }
3281
3282 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
3283 {
3284         DE_UNREF(mipLevel);
3285
3286         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
3287                                                                                                 region.imageBlit.srcOffsets[1],
3288                                                                                                 region.imageBlit.dstOffsets[0],
3289                                                                                                 region.imageBlit.dstOffsets[1]);
3290
3291         flipCoordinates(region, mirrorMode);
3292
3293         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
3294         const VkOffset3D                                        srcExtent               =
3295         {
3296                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
3297                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
3298                 region.imageBlit.srcOffsets[1].z - srcOffset.z,
3299         };
3300         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
3301         const VkOffset3D                                        dstExtent               =
3302         {
3303                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
3304                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
3305                 region.imageBlit.dstOffsets[1].z - dstOffset.z,
3306         };
3307
3308         tcu::Sampler::FilterMode                filter;
3309         switch (m_params.filter)
3310         {
3311                 case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
3312                 case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
3313                 case VK_FILTER_NEAREST:
3314                 default:                                        filter = tcu::Sampler::NEAREST;  break;
3315         }
3316
3317         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
3318         {
3319                 DE_ASSERT(src.getFormat() == dst.getFormat());
3320
3321                 // Scale depth.
3322                 if (tcu::hasDepthComponent(src.getFormat().order))
3323                 {
3324                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
3325                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
3326                         tcu::scale(dstSubRegion, srcSubRegion, filter);
3327
3328                         if (filter != tcu::Sampler::NEAREST)
3329                         {
3330                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
3331                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
3332                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
3333                         }
3334                 }
3335
3336                 // Scale stencil.
3337                 if (tcu::hasStencilComponent(src.getFormat().order))
3338                 {
3339                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
3340                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
3341                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
3342
3343                         if (filter != tcu::Sampler::NEAREST)
3344                         {
3345                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
3346                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
3347                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
3348                         }
3349                 }
3350         }
3351         else
3352         {
3353                 const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
3354                 const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
3355                 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
3356
3357                 if (filter != tcu::Sampler::NEAREST)
3358                 {
3359                         const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
3360                         scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
3361                 }
3362         }
3363 }
3364
3365 void BlittingImages::generateExpectedResult (void)
3366 {
3367         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
3368         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
3369
3370         m_expectedTextureLevel[0]               = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
3371         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
3372
3373         if (m_params.filter != VK_FILTER_NEAREST)
3374         {
3375                 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
3376                 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
3377         }
3378
3379         for (deUint32 i = 0; i < m_params.regions.size(); i++)
3380         {
3381                 CopyRegion region = m_params.regions[i];
3382                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
3383         }
3384 }
3385
3386 class BlitImageTestCase : public vkt::TestCase
3387 {
3388 public:
3389                                                         BlitImageTestCase               (tcu::TestContext&                              testCtx,
3390                                                                                                          const std::string&                             name,
3391                                                                                                          const std::string&                             description,
3392                                                                                                          const TestParams                               params)
3393                                                                 : vkt::TestCase (testCtx, name, description)
3394                                                                 , m_params              (params)
3395         {}
3396
3397         virtual TestInstance*   createInstance                  (Context&                                               context) const
3398         {
3399                 return new BlittingImages(context, m_params);
3400         }
3401
3402         virtual void                    checkSupport                    (Context&                                               context) const
3403         {
3404                 VkImageFormatProperties properties;
3405                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3406                                                                                                                                                                         m_params.src.image.format,
3407                                                                                                                                                                         m_params.src.image.imageType,
3408                                                                                                                                                                         m_params.src.image.tiling,
3409                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3410                                                                                                                                                                         0,
3411                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
3412                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3413                                                                                                                                                                         m_params.dst.image.format,
3414                                                                                                                                                                         m_params.dst.image.imageType,
3415                                                                                                                                                                         m_params.dst.image.tiling,
3416                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3417                                                                                                                                                                         0,
3418                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
3419                 {
3420                         TCU_THROW(NotSupportedError, "Format not supported");
3421                 }
3422
3423                 VkFormatProperties srcFormatProperties;
3424                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
3425                 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
3426                 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
3427                 {
3428                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
3429                 }
3430
3431                 VkFormatProperties dstFormatProperties;
3432                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
3433                 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
3434                 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
3435                 {
3436                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
3437                 }
3438
3439                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
3440                 {
3441                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
3442                 }
3443
3444                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
3445                 {
3446                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
3447
3448                         if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
3449                         {
3450                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
3451                         }
3452                 }
3453
3454                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
3455                 {
3456                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
3457                         {
3458                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
3459                         }
3460                 }
3461         }
3462
3463 private:
3464         TestParams                              m_params;
3465 };
3466
3467 class BlittingMipmaps : public CopiesAndBlittingTestInstance
3468 {
3469 public:
3470                                                                                 BlittingMipmaps                                 (Context&   context,
3471                                                                                                                                                  TestParams params);
3472         virtual tcu::TestStatus                         iterate                                                 (void);
3473 protected:
3474         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
3475         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
3476         virtual void                                            generateExpectedResult                  (void);
3477 private:
3478         bool                                                            checkNonNearestFilteredResult   (void);
3479         bool                                                            checkNearestFilteredResult              (void);
3480
3481         Move<VkImage>                                           m_source;
3482         de::MovePtr<Allocation>                         m_sourceImageAlloc;
3483         Move<VkImage>                                           m_destination;
3484         de::MovePtr<Allocation>                         m_destinationImageAlloc;
3485
3486         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel[16];
3487 };
3488
3489 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
3490         : CopiesAndBlittingTestInstance (context, params)
3491 {
3492         const InstanceInterface&        vki                                     = context.getInstanceInterface();
3493         const DeviceInterface&          vk                                      = context.getDeviceInterface();
3494         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
3495         const VkDevice                          vkDevice                        = context.getDevice();
3496         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
3497         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
3498
3499         // Create source image
3500         {
3501                 const VkImageCreateInfo         sourceImageParams               =
3502                 {
3503                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3504                         DE_NULL,                                                                // const void*                  pNext;
3505                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
3506                         m_params.src.image.imageType,                   // VkImageType                  imageType;
3507                         m_params.src.image.format,                              // VkFormat                             format;
3508                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
3509                         1u,                                                                             // deUint32                             mipLevels;
3510                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
3511                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3512                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
3513                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3514                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3515                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3516                         1u,                                                                             // deUint32                             queueFamilyCount;
3517                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3518                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3519                 };
3520
3521                 m_source = createImage(vk, vkDevice, &sourceImageParams);
3522                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3523                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3524         }
3525
3526         // Create destination image
3527         {
3528                 const VkImageCreateInfo         destinationImageParams  =
3529                 {
3530                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3531                         DE_NULL,                                                                // const void*                  pNext;
3532                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
3533                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
3534                         m_params.dst.image.format,                              // VkFormat                             format;
3535                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
3536                         m_params.mipLevels,                                             // deUint32                             mipLevels;
3537                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
3538                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3539                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
3540                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3541                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3542                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3543                         1u,                                                                             // deUint32                             queueFamilyCount;
3544                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3545                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3546                 };
3547
3548                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3549                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3550                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3551         }
3552 }
3553
3554 tcu::TestStatus BlittingMipmaps::iterate (void)
3555 {
3556         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
3557         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
3558         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
3559                                                                                                                                                                 m_params.src.image.extent.width,
3560                                                                                                                                                                 m_params.src.image.extent.height,
3561                                                                                                                                                                 m_params.src.image.extent.depth));
3562         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
3563         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
3564                                                                                                                                                                                 (int)m_params.dst.image.extent.width,
3565                                                                                                                                                                                 (int)m_params.dst.image.extent.height,
3566                                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
3567         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
3568         generateExpectedResult();
3569
3570         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
3571
3572         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
3573
3574         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
3575         const VkDevice                          vkDevice                        = m_context.getDevice();
3576         const VkQueue                           queue                           = m_context.getUniversalQueue();
3577
3578         std::vector<VkImageBlit>                regions;
3579         std::vector<VkImageBlit2KHR>    regions2KHR;
3580         for (deUint32 i = 0; i < m_params.regions.size(); i++)
3581         {
3582                 if (m_params.extensionUse == EXTENSION_USE_NONE)
3583                 {
3584                         regions.push_back(m_params.regions[i].imageBlit);
3585                 }
3586                 else
3587                 {
3588                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3589                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
3590                 }
3591         }
3592
3593         // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
3594         if (!m_params.singleCommand)
3595                 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
3596
3597         beginCommandBuffer(vk, *m_cmdBuffer);
3598
3599         // Blit all mip levels with a single blit command
3600         if (m_params.singleCommand)
3601         {
3602                 {
3603                         // Source image layout
3604                         const VkImageMemoryBarrier              srcImageBarrier         =
3605                         {
3606                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3607                                 DE_NULL,                                                                        // const void*                          pNext;
3608                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3609                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3610                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3611                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
3612                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3613                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3614                                 m_source.get(),                                                         // VkImage                                      image;
3615                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3616                                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
3617                                         0u,                                                                     // deUint32                             baseMipLevel;
3618                                         1u,                                                                     // deUint32                             mipLevels;
3619                                         0u,                                                                     // deUint32                             baseArraySlice;
3620                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
3621                                 }
3622                         };
3623
3624                         // Destination image layout
3625                         const VkImageMemoryBarrier              dstImageBarrier         =
3626                         {
3627                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3628                                 DE_NULL,                                                                        // const void*                          pNext;
3629                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3630                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3631                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3632                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
3633                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3634                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3635                                 m_destination.get(),                                            // VkImage                                      image;
3636                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3637                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
3638                                         0u,                                                                     // deUint32                             baseMipLevel;
3639                                         m_params.mipLevels,                                     // deUint32                             mipLevels;
3640                                         0u,                                                                     // deUint32                             baseArraySlice;
3641                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3642                                 }
3643                         };
3644
3645                         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);
3646                         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);
3647
3648                         if (m_params.extensionUse == EXTENSION_USE_NONE)
3649                         {
3650                                 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);
3651                         }
3652                         else
3653                         {
3654                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3655                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
3656                                 {
3657                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
3658                                         DE_NULL,                                                                        // const void*                                  pNext;
3659                                         m_source.get(),                                                         // VkImage                                              srcImage;
3660                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
3661                                         m_destination.get(),                                            // VkImage                                              dstImage;
3662                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
3663                                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
3664                                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
3665                                         m_params.filter                                                         // VkFilter                                             filter;
3666                                 };
3667                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
3668                         }
3669                 }
3670         }
3671         // Blit mip levels with multiple blit commands
3672         else
3673         {
3674                 // Prepare all mip levels for reading
3675                 {
3676                         for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
3677                         {
3678                                 VkImageMemoryBarrier preImageBarrier =
3679                                 {
3680                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType      sType;
3681                                         DE_NULL,                                                                                                                                // const void*          pNext;
3682                                         VK_ACCESS_TRANSFER_WRITE_BIT,                                                                                   // VkAccessFlags        srcAccessMask;
3683                                         VK_ACCESS_TRANSFER_READ_BIT,                                                                                    // VkAccessFlags        dstAccessMask;
3684                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                                                                   // VkImageLayout        oldLayout;
3685                                         m_params.src.image.operationLayout,                                                                             // VkImageLayout        newLayout;
3686                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     srcQueueFamilyIndex;
3687                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     dstQueueFamilyIndex;
3688                                         m_destination.get(),                                                                                                    // VkImage                      image;
3689                                         {                                                                                                                                               // VkImageSubresourceRange      subresourceRange;
3690                                                 getAspectFlags(dstTcuFormat),                                                                           // VkImageAspectFlags   aspectMask;
3691                                                         0u,                                                                                                                             // deUint32                             baseMipLevel;
3692                                                         VK_REMAINING_MIP_LEVELS,                                                                                // deUint32                             mipLevels;
3693                                                         0u,                                                                                                                             // deUint32                             baseArraySlice;
3694                                                         getArraySize(m_params.src.image)                                                                // deUint32                             arraySize;
3695                                         }
3696                                 };
3697
3698                                 if (getArraySize(m_params.src.image) == 1)
3699                                 {
3700                                         DE_ASSERT(barrierno < m_params.mipLevels);
3701                                         preImageBarrier.subresourceRange.baseMipLevel   = barrierno;
3702                                         preImageBarrier.subresourceRange.levelCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
3703                                 }
3704                                 else
3705                                 {
3706                                         preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
3707                                         preImageBarrier.subresourceRange.layerCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
3708                                 }
3709                                 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);
3710                         }
3711                 }
3712
3713                 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
3714                 {
3715                         const deUint32  mipLevel        = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
3716
3717                         // Prepare single mip level for writing
3718                         const VkImageMemoryBarrier              preImageBarrier         =
3719                         {
3720                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3721                                 DE_NULL,                                                                        // const void*                                  pNext;
3722                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
3723                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3724                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
3725                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
3726                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3727                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3728                                 m_destination.get(),                                            // VkImage                                      image;
3729                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3730                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
3731                                         mipLevel,                                                       // deUint32                             baseMipLevel;
3732                                         1u,                                                                     // deUint32                             mipLevels;
3733                                         0u,                                                                     // deUint32                             baseArraySlice;
3734                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3735                                 }
3736                         };
3737
3738                         // Prepare single mip level for reading
3739                         const VkImageMemoryBarrier              postImageBarrier        =
3740                         {
3741                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3742                                 DE_NULL,                                                                        // const void*                          pNext;
3743                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3744                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3745                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        oldLayout;
3746                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
3747                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3748                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3749                                 m_destination.get(),                                            // VkImage                                      image;
3750                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3751                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
3752                                         mipLevel,                                                       // deUint32                             baseMipLevel;
3753                                         1u,                                                                     // deUint32                             mipLevels;
3754                                         0u,                                                                     // deUint32                             baseArraySlice;
3755                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
3756                                 }
3757                         };
3758
3759                         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);
3760
3761                         if (m_params.extensionUse == EXTENSION_USE_NONE)
3762                         {
3763                                 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);
3764                         }
3765                         else
3766                         {
3767                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3768                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
3769                                 {
3770                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
3771                                         DE_NULL,                                                                        // const void*                                  pNext;
3772                                         m_destination.get(),                                            // VkImage                                              srcImage;
3773                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
3774                                         m_destination.get(),                                            // VkImage                                              dstImage;
3775                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
3776                                         1u,                                                                                     // uint32_t                                             regionCount;
3777                                         &regions2KHR[regionNdx],                                        // const VkImageBlit2KHR*               pRegions;
3778                                         m_params.filter                                                         // VkFilter                                             filter;
3779                                 };
3780                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
3781                         }
3782
3783                         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);
3784                 }
3785
3786                 // Prepare all mip levels for writing
3787                 {
3788                         const VkImageMemoryBarrier              postImageBarrier                =
3789                         {
3790                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3791                                 DE_NULL,                                                                        // const void*                          pNext;
3792                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
3793                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3794                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
3795                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
3796                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3797                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3798                                 m_destination.get(),                                            // VkImage                                      image;
3799                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
3800                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
3801                                         0u,                                                                     // deUint32                             baseMipLevel;
3802                                         VK_REMAINING_MIP_LEVELS,                        // deUint32                             mipLevels;
3803                                         0u,                                                                     // deUint32                             baseArraySlice;
3804                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
3805                                 }
3806                         };
3807
3808                         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);
3809                 }
3810         }
3811
3812         endCommandBuffer(vk, *m_cmdBuffer);
3813         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3814
3815         return checkTestResult();
3816 }
3817
3818 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
3819 {
3820         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
3821         bool                                            allLevelsOk             = true;
3822
3823         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
3824         {
3825                 // Update reference results with previous results that have been verified.
3826                 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
3827                 for (deUint32 i = 0; i < m_params.regions.size(); i++)
3828                 {
3829                         const CopyRegion region = m_params.regions[i];
3830                         const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
3831                         const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
3832                         de::MovePtr<tcu::TextureLevel>  prevResultLevel;
3833                         tcu::ConstPixelBufferAccess src;
3834                         if (srcMipLevel < mipLevelNdx)
3835                         {
3836                                 // Generate expected result from rendered result that was previously verified
3837                                 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
3838                                 src = prevResultLevel->getAccess();
3839                         }
3840                         else
3841                         {
3842                                 // Previous reference mipmaps might have changed, so recompute expected result
3843                                 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
3844                         }
3845                         copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
3846                 }
3847
3848                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
3849                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
3850
3851                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
3852                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
3853                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
3854                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3855                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3856                                                                                                                                                                                                                                                                         resultAccess;
3857                 const tcu::ConstPixelBufferAccess               clampedLevel            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
3858                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
3859                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx]->getAccess();
3860                 const tcu::ConstPixelBufferAccess               unclampedLevel          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
3861                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
3862                                                                                                                                                                                                                                                                         m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
3863                 const tcu::TextureFormat                                srcFormat                       = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
3864                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
3865                                                                                                                                                                                                                                                                         mapVkFormat(m_params.src.image.format);
3866
3867                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
3868                 bool                                                                    singleLevelOk           = false;
3869                 std::vector <CopyRegion>                                mipLevelRegions;
3870
3871                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
3872                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
3873                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
3874
3875                 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3876
3877                 if (isFloatFormat(dstFormat))
3878                 {
3879                         const bool              srcIsSRGB   = tcu::isSRGB(srcFormat);
3880                         const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3881                         const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
3882                         const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
3883
3884                         singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3885                         log << tcu::TestLog::EndSection;
3886
3887                         if (!singleLevelOk)
3888                         {
3889                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3890                                 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3891                                 log << tcu::TestLog::EndSection;
3892                         }
3893                 }
3894                 else
3895                 {
3896                         tcu::UVec4  threshold;
3897                         // Calculate threshold depending on channel width of destination format.
3898                         const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
3899                         const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3900                         for (deUint32 i = 0; i < 4; ++i)
3901                                 threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3902
3903                         singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3904                         log << tcu::TestLog::EndSection;
3905
3906                         if (!singleLevelOk)
3907                         {
3908                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3909                                 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3910                                 log << tcu::TestLog::EndSection;
3911                         }
3912                 }
3913                 allLevelsOk &= singleLevelOk;
3914         }
3915
3916         return allLevelsOk;
3917 }
3918
3919 bool BlittingMipmaps::checkNearestFilteredResult (void)
3920 {
3921         bool                                            allLevelsOk             = true;
3922         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
3923
3924         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
3925         {
3926                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
3927                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
3928
3929                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
3930                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
3931                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
3932                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3933                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3934                                                                                                                                                                                                                                                                         resultAccess;
3935                 const tcu::ConstPixelBufferAccess               source                          = (m_params.singleCommand || mipLevelNdx == 0) ?                        //  Read from source image
3936                                                                                                                                           tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
3937                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
3938                                                                                                                                                                                                                                                                         m_sourceTextureLevel->getAccess()
3939                                                                                                                                                                                                                                                                 //  Read from destination image
3940                                                                                                                                         : tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
3941                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
3942                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
3943                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
3944                 const tcu::TextureChannelClass                  dstChannelClass         = tcu::getTextureChannelClass(dstFormat.type);
3945                 bool                                                                    singleLevelOk           = false;
3946                 std::vector <CopyRegion>                                mipLevelRegions;
3947
3948                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
3949                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
3950                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
3951
3952                 tcu::TextureLevel                               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3953                 tcu::PixelBufferAccess                  errorMask                       = errorMaskStorage.getAccess();
3954                 tcu::Vec4                                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3955                 tcu::Vec4                                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3956
3957                 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3958
3959                 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3960                         dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
3961                 {
3962                         singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
3963                 }
3964                 else
3965                         singleLevelOk = floatNearestBlitCompare(source, result, errorMask, mipLevelRegions);
3966
3967                 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3968                         tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3969
3970                 if (!singleLevelOk)
3971                 {
3972                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
3973                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3974                                 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
3975                                 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
3976                                 << tcu::TestLog::EndImageSet;
3977                 }
3978                 else
3979                 {
3980                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
3981                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3982                                 << tcu::TestLog::EndImageSet;
3983                 }
3984
3985                 allLevelsOk &= singleLevelOk;
3986         }
3987
3988         return allLevelsOk;
3989 }
3990
3991 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
3992 {
3993         DE_UNREF(result);
3994         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
3995         const std::string failMessage("Result image is incorrect");
3996
3997         if (m_params.filter != VK_FILTER_NEAREST)
3998         {
3999                 if (!checkNonNearestFilteredResult())
4000                         return tcu::TestStatus::fail(failMessage);
4001         }
4002         else // NEAREST filtering
4003         {
4004                 if (!checkNearestFilteredResult())
4005                         return tcu::TestStatus::fail(failMessage);
4006         }
4007
4008         return tcu::TestStatus::pass("Pass");
4009 }
4010
4011 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4012 {
4013         DE_ASSERT(src.getDepth() == dst.getDepth());
4014
4015         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4016                                                                                                 region.imageBlit.srcOffsets[1],
4017                                                                                                 region.imageBlit.dstOffsets[0],
4018                                                                                                 region.imageBlit.dstOffsets[1]);
4019
4020         flipCoordinates(region, mirrorMode);
4021
4022         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
4023         const VkOffset3D                                        srcExtent               =
4024         {
4025                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4026                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4027                 region.imageBlit.srcOffsets[1].z - srcOffset.z
4028         };
4029         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
4030         const VkOffset3D                                        dstExtent               =
4031         {
4032                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4033                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4034                 region.imageBlit.dstOffsets[1].z - dstOffset.z
4035         };
4036
4037         tcu::Sampler::FilterMode                filter;
4038         switch (m_params.filter)
4039         {
4040         case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
4041         case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
4042         case VK_FILTER_NEAREST:
4043         default:                                        filter = tcu::Sampler::NEAREST;  break;
4044         }
4045
4046         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4047         {
4048                 DE_ASSERT(src.getFormat() == dst.getFormat());
4049                 // Scale depth.
4050                 if (tcu::hasDepthComponent(src.getFormat().order))
4051                 {
4052                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
4053                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
4054                         tcu::scale(dstSubRegion, srcSubRegion, filter);
4055
4056                         if (filter != tcu::Sampler::NEAREST)
4057                         {
4058                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4059                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
4060                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
4061                         }
4062                 }
4063
4064                 // Scale stencil.
4065                 if (tcu::hasStencilComponent(src.getFormat().order))
4066                 {
4067                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
4068                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
4069                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4070
4071                         if (filter != tcu::Sampler::NEAREST)
4072                         {
4073                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4074                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
4075                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
4076                         }
4077                 }
4078         }
4079         else
4080         {
4081                 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
4082                 {
4083                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
4084                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
4085                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4086
4087                         if (filter != tcu::Sampler::NEAREST)
4088                         {
4089                                 const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
4090                                 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
4091                         }
4092                 }
4093         }
4094 }
4095
4096 void BlittingMipmaps::generateExpectedResult (void)
4097 {
4098         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
4099         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
4100
4101         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4102                 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
4103
4104         tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
4105
4106         if (m_params.filter != VK_FILTER_NEAREST)
4107         {
4108                 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4109                         m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
4110
4111                 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
4112         }
4113
4114         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4115         {
4116                 CopyRegion region = m_params.regions[i];
4117                 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);
4118         }
4119 }
4120
4121 class BlitMipmapTestCase : public vkt::TestCase
4122 {
4123 public:
4124                                                         BlitMipmapTestCase              (tcu::TestContext&                              testCtx,
4125                                                                                                          const std::string&                             name,
4126                                                                                                          const std::string&                             description,
4127                                                                                                          const TestParams                               params)
4128                                                                 : vkt::TestCase (testCtx, name, description)
4129                                                                 , m_params              (params)
4130         {}
4131
4132         virtual TestInstance*   createInstance                  (Context&                                               context) const
4133         {
4134                 return new BlittingMipmaps(context, m_params);
4135         }
4136
4137         virtual void                    checkSupport                    (Context&                                               context) const
4138         {
4139                 const InstanceInterface&        vki                                     = context.getInstanceInterface();
4140                 const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
4141                 {
4142                         VkImageFormatProperties properties;
4143                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4144                                                                                                                                                                                 m_params.src.image.format,
4145                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
4146                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
4147                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4148                                                                                                                                                                                 0,
4149                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4150                         {
4151                                 TCU_THROW(NotSupportedError, "Format not supported");
4152                         }
4153                         else if ((m_params.src.image.extent.width       > properties.maxExtent.width)   ||
4154                                                 (m_params.src.image.extent.height       > properties.maxExtent.height)  ||
4155                                                 (m_params.src.image.extent.depth        > properties.maxArrayLayers))
4156                         {
4157                                 TCU_THROW(NotSupportedError, "Image size not supported");
4158                         }
4159                 }
4160
4161                 {
4162                         VkImageFormatProperties properties;
4163                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4164                                                                                                                                                                                 m_params.dst.image.format,
4165                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
4166                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
4167                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4168                                                                                                                                                                                 0,
4169                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4170                         {
4171                                 TCU_THROW(NotSupportedError, "Format not supported");
4172                         }
4173                         else if ((m_params.dst.image.extent.width       > properties.maxExtent.width)   ||
4174                                                 (m_params.dst.image.extent.height       > properties.maxExtent.height)  ||
4175                                                 (m_params.dst.image.extent.depth        > properties.maxArrayLayers))
4176                         {
4177                                 TCU_THROW(NotSupportedError, "Image size not supported");
4178                         }
4179                         else if (m_params.mipLevels > properties.maxMipLevels)
4180                         {
4181                                 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
4182                         }
4183                         else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)        &&
4184                                          (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
4185                         {
4186                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4187                         }
4188                 }
4189
4190                 const VkFormatProperties        srcFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
4191                 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4192                 {
4193                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4194                 }
4195
4196                 const VkFormatProperties        dstFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
4197                 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4198                 {
4199                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4200                 }
4201
4202                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4203                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4204
4205                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4206                 {
4207                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4208
4209                         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4210                         {
4211                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4212                         }
4213                 }
4214         }
4215
4216 private:
4217         TestParams                              m_params;
4218 };
4219
4220 // Resolve image to image.
4221
4222 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
4223 class ResolveImageToImage : public CopiesAndBlittingTestInstance
4224 {
4225 public:
4226                                                                                                 ResolveImageToImage                     (Context&                                                       context,
4227                                                                                                                                                          TestParams                                                     params,
4228                                                                                                                                                          const ResolveImageToImageOptions       options);
4229         virtual tcu::TestStatus                                         iterate                                         (void);
4230 protected:
4231         virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4232         void                                                                            copyMSImageToMSImage            (deUint32 copyArraySize);
4233         tcu::TestStatus                                                         checkIntermediateCopy           (void);
4234 private:
4235         Move<VkImage>                                                           m_multisampledImage;
4236         de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
4237
4238         Move<VkImage>                                                           m_destination;
4239         de::MovePtr<Allocation>                                         m_destinationImageAlloc;
4240
4241         Move<VkImage>                                                           m_multisampledCopyImage;
4242         de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
4243
4244         const ResolveImageToImageOptions                        m_options;
4245
4246         virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
4247                                                                                                                                                          tcu::PixelBufferAccess                 dst,
4248                                                                                                                                                          CopyRegion                                             region,
4249                                                                                                                                                          deUint32                                               mipLevel = 0u);
4250 };
4251
4252 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
4253         : CopiesAndBlittingTestInstance (context, params)
4254         , m_options                                             (options)
4255 {
4256         const InstanceInterface&        vki                                             = m_context.getInstanceInterface();
4257         const DeviceInterface&          vk                                              = m_context.getDeviceInterface();
4258         const VkPhysicalDevice          vkPhysDevice                    = m_context.getPhysicalDevice();
4259         const VkDevice                          vkDevice                                = m_context.getDevice();
4260         const deUint32                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
4261         Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
4262
4263         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
4264         Move<VkRenderPass>                      renderPass;
4265
4266         Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
4267         Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
4268         std::vector<tcu::Vec4>          vertices;
4269
4270         Move<VkBuffer>                          vertexBuffer;
4271         de::MovePtr<Allocation>         vertexBufferAlloc;
4272
4273         Move<VkPipelineLayout>          pipelineLayout;
4274         Move<VkPipeline>                        graphicsPipeline;
4275
4276         const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
4277
4278         // Create color image.
4279         {
4280                 VkImageCreateInfo       colorImageParams        =
4281                 {
4282                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
4283                         DE_NULL,                                                                                                                                // const void*                          pNext;
4284                         getCreateFlags(m_params.src.image),                                                                             // VkImageCreateFlags           flags;
4285                         m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
4286                         m_params.src.image.format,                                                                                              // VkFormat                                     format;
4287                         getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
4288                         1u,                                                                                                                                             // deUint32                                     mipLevels;
4289                         getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
4290                         rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
4291                         VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
4292                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                                                                             // VkImageUsageFlags            usage;
4293                                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
4294                                 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
4295                         VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
4296                         1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
4297                         &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
4298                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
4299                 };
4300
4301                 m_multisampledImage                                             = createImage(vk, vkDevice, &colorImageParams);
4302
4303                 // Allocate and bind color image memory.
4304                 m_multisampledImageAlloc                                = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4305                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
4306
4307                 switch (m_options)
4308                 {
4309                         case COPY_MS_IMAGE_TO_MS_IMAGE:
4310                         {
4311                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4312                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
4313                                 // Allocate and bind color image memory.
4314                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4315                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
4316                                 break;
4317                         }
4318
4319                         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
4320                         {
4321                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4322                                 colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
4323                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
4324                                 // Allocate and bind color image memory.
4325                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4326                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
4327                                 break;
4328                         }
4329
4330                         default :
4331                                 break;
4332                 }
4333         }
4334
4335         // Create destination image.
4336         {
4337                 const VkImageCreateInfo destinationImageParams  =
4338                 {
4339                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
4340                         DE_NULL,                                                                // const void*                  pNext;
4341                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
4342                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
4343                         m_params.dst.image.format,                              // VkFormat                             format;
4344                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
4345                         1u,                                                                             // deUint32                             mipLevels;
4346                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
4347                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
4348                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
4349                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4350                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
4351                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
4352                         1u,                                                                             // deUint32                             queueFamilyCount;
4353                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
4354                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
4355                 };
4356
4357                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
4358                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4359                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4360         }
4361
4362         // Barriers for copying image to buffer
4363         VkImageMemoryBarrier            srcImageBarrier         =
4364         {
4365                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4366                 DE_NULL,                                                                        // const void*                          pNext;
4367                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
4368                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
4369                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
4370                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
4371                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4372                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4373                 m_multisampledImage.get(),                                      // VkImage                                      image;
4374                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4375                         VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
4376                         0u,                                                                     // deUint32                             baseMipLevel;
4377                         1u,                                                                     // deUint32                             mipLevels;
4378                         0u,                                                                     // deUint32                             baseArraySlice;
4379                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
4380                 }
4381         };
4382
4383         // Create render pass.
4384         {
4385                 const VkAttachmentDescription   attachmentDescriptions[1]       =
4386                 {
4387                         {
4388                                 0u,                                                                                     // VkAttachmentDescriptionFlags         flags;
4389                                 m_params.src.image.format,                                      // VkFormat                                                     format;
4390                                 rasterizationSamples,                                           // VkSampleCountFlagBits                        samples;
4391                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
4392                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
4393                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
4394                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
4395                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
4396                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
4397                         },
4398                 };
4399
4400                 const VkAttachmentReference             colorAttachmentReference        =
4401                 {
4402                         0u,                                                                                                     // deUint32                     attachment;
4403                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
4404                 };
4405
4406                 const VkSubpassDescription              subpassDescription                      =
4407                 {
4408                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
4409                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
4410                         0u,                                                                     // deUint32                                             inputAttachmentCount;
4411                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
4412                         1u,                                                                     // deUint32                                             colorAttachmentCount;
4413                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
4414                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
4415                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
4416                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
4417                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
4418                 };
4419
4420                 const VkRenderPassCreateInfo    renderPassParams                        =
4421                 {
4422                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
4423                         DE_NULL,                                                                        // const void*                                          pNext;
4424                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
4425                         1u,                                                                                     // deUint32                                                     attachmentCount;
4426                         attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments;
4427                         1u,                                                                                     // deUint32                                                     subpassCount;
4428                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
4429                         0u,                                                                                     // deUint32                                                     dependencyCount;
4430                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
4431                 };
4432
4433                 renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
4434         }
4435
4436         // Create pipeline layout
4437         {
4438                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
4439                 {
4440                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
4441                         DE_NULL,                                                                                        // const void*                                          pNext;
4442                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
4443                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
4444                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
4445                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
4446                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
4447                 };
4448
4449                 pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
4450         }
4451
4452         // Create upper half triangle.
4453         {
4454                 const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
4455                 const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
4456                 const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
4457                 // Add triangle.
4458                 vertices.push_back(a);
4459                 vertices.push_back(c);
4460                 vertices.push_back(b);
4461         }
4462
4463         // Create vertex buffer.
4464         {
4465                 const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
4466                 const VkBufferCreateInfo        vertexBufferParams      =
4467                 {
4468                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
4469                         DE_NULL,                                                                        // const void*                  pNext;
4470                         0u,                                                                                     // VkBufferCreateFlags  flags;
4471                         vertexDataSize,                                                         // VkDeviceSize                 size;
4472                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
4473                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
4474                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
4475                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
4476                 };
4477
4478                 vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
4479                 vertexBufferAlloc       = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4480                 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
4481
4482                 // Load vertices into vertex buffer.
4483                 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
4484                 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
4485         }
4486
4487         {
4488                 Move<VkFramebuffer>             framebuffer;
4489                 Move<VkImageView>               sourceAttachmentView;
4490
4491                 // Create color attachment view.
4492                 {
4493                         const VkImageViewCreateInfo     colorAttachmentViewParams       =
4494                         {
4495                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
4496                                 DE_NULL,                                                                                                // const void*                          pNext;
4497                                 0u,                                                                                                             // VkImageViewCreateFlags       flags;
4498                                 *m_multisampledImage,                                                                   // VkImage                                      image;
4499                                 VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
4500                                 m_params.src.image.format,                                                              // VkFormat                                     format;
4501                                 componentMappingRGBA,                                                                   // VkComponentMapping           components;
4502                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
4503                         };
4504                         sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
4505                 }
4506
4507                 // Create framebuffer
4508                 {
4509                         const VkImageView                               attachments[1]          =
4510                         {
4511                                         *sourceAttachmentView,
4512                         };
4513
4514                         const VkFramebufferCreateInfo   framebufferParams       =
4515                         {
4516                                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
4517                                         DE_NULL,                                                                                        // const void*                                  pNext;
4518                                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
4519                                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
4520                                         1u,                                                                                                     // deUint32                                             attachmentCount;
4521                                         attachments,                                                                            // const VkImageView*                   pAttachments;
4522                                         m_params.src.image.extent.width,                                        // deUint32                                             width;
4523                                         m_params.src.image.extent.height,                                       // deUint32                                             height;
4524                                         1u                                                                                                      // deUint32                                             layers;
4525                         };
4526
4527                         framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
4528                 }
4529
4530                 // Create pipeline
4531                 {
4532                         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
4533                         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
4534
4535                         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
4536                         {
4537                                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
4538                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
4539                                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
4540                                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
4541                                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
4542                                 0.0f,                                                                                                           // float                                                                        minSampleShading;
4543                                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
4544                                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
4545                                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
4546                         };
4547
4548                         graphicsPipeline = makeGraphicsPipeline(vk,                                                                             // const DeviceInterface&                        vk
4549                                                                                                         vkDevice,                                                               // const VkDevice                                device
4550                                                                                                         *pipelineLayout,                                                // const VkPipelineLayout                        pipelineLayout
4551                                                                                                         *vertexShaderModule,                                    // const VkShaderModule                          vertexShaderModule
4552                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
4553                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
4554                                                                                                         DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
4555                                                                                                         *fragmentShaderModule,                                  // const VkShaderModule                          fragmentShaderModule
4556                                                                                                         *renderPass,                                                    // const VkRenderPass                            renderPass
4557                                                                                                         viewports,                                                              // const std::vector<VkViewport>&                viewports
4558                                                                                                         scissors,                                                               // const std::vector<VkRect2D>&                  scissors
4559                                                                                                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
4560                                                                                                         0u,                                                                             // const deUint32                                subpass
4561                                                                                                         0u,                                                                             // const deUint32                                patchControlPoints
4562                                                                                                         DE_NULL,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
4563                                                                                                         DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
4564                                                                                                         &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
4565                 }
4566
4567                 // Create command buffer
4568                 {
4569                         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
4570                         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);
4571                         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));
4572
4573                         const VkDeviceSize      vertexBufferOffset      = 0u;
4574
4575                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
4576                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
4577                         vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
4578
4579                         endRenderPass(vk, *m_cmdBuffer);
4580                         endCommandBuffer(vk, *m_cmdBuffer);
4581                 }
4582
4583                 // Queue submit.
4584                 {
4585                         const VkQueue   queue   = m_context.getUniversalQueue();
4586                         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
4587                 }
4588         }
4589 }
4590
4591 tcu::TestStatus ResolveImageToImage::iterate (void)
4592 {
4593         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
4594         const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
4595
4596         // upload the destination image
4597         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4598                                                                                                                                                         (int)m_params.dst.image.extent.width,
4599                                                                                                                                                         (int)m_params.dst.image.extent.height,
4600                                                                                                                                                         (int)m_params.dst.image.extent.depth));
4601         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
4602         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
4603
4604         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4605                                                                                                                                         (int)m_params.src.image.extent.width,
4606                                                                                                                                         (int)m_params.src.image.extent.height,
4607                                                                                                                                         (int)m_params.dst.image.extent.depth));
4608
4609         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);
4610         generateExpectedResult();
4611
4612         VkImage         sourceImage             = m_multisampledImage.get();
4613         deUint32        sourceArraySize = getArraySize(m_params.src.image);
4614
4615         switch (m_options)
4616         {
4617                 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
4618                         // Duplicate the multisampled image to a multisampled image array
4619                         sourceArraySize = getArraySize(m_params.dst.image); // fall through
4620                 case COPY_MS_IMAGE_TO_MS_IMAGE:
4621                         copyMSImageToMSImage(sourceArraySize);
4622                         sourceImage     = m_multisampledCopyImage.get();
4623                         break;
4624                 default:
4625                         break;
4626         }
4627
4628         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
4629         const VkDevice                                  vkDevice                        = m_context.getDevice();
4630         const VkQueue                                   queue                           = m_context.getUniversalQueue();
4631
4632         std::vector<VkImageResolve>             imageResolves;
4633         std::vector<VkImageResolve2KHR> imageResolves2KHR;
4634         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4635         {
4636                 if (m_params.extensionUse == EXTENSION_USE_NONE)
4637                 {
4638                         imageResolves.push_back(m_params.regions[i].imageResolve);
4639                 }
4640                 else
4641                 {
4642                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4643                         imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
4644                 }
4645         }
4646
4647         const VkImageMemoryBarrier      imageBarriers[]         =
4648         {
4649                 // source image
4650                 {
4651                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4652                         DE_NULL,                                                                        // const void*                          pNext;
4653                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
4654                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
4655                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
4656                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
4657                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4658                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4659                         sourceImage,                                                            // VkImage                                      image;
4660                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
4661                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
4662                                 0u,                                                                     // deUint32                             baseMipLevel;
4663                                 1u,                                                                     // deUint32                             mipLevels;
4664                                 0u,                                                                     // deUint32                             baseArraySlice;
4665                                 sourceArraySize                                         // deUint32                             arraySize;
4666                         }
4667                 },
4668                 // destination image
4669                 {
4670                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4671                         DE_NULL,                                                                        // const void*                          pNext;
4672                         0u,                                                                                     // VkAccessFlags                        srcAccessMask;
4673                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4674                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
4675                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
4676                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4677                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4678                         m_destination.get(),                                            // VkImage                                      image;
4679                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
4680                                 getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4681                                 0u,                                                                     // deUint32                             baseMipLevel;
4682                                 1u,                                                                     // deUint32                             mipLevels;
4683                                 0u,                                                                     // deUint32                             baseArraySlice;
4684                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4685                         }
4686                 },
4687         };
4688
4689         const VkImageMemoryBarrier postImageBarrier =
4690         {
4691                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
4692                 DE_NULL,                                                                // const void*                          pNext;
4693                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask;
4694                 VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags                        dstAccessMask;
4695                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        oldLayout;
4696                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
4697                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
4698                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
4699                 m_destination.get(),                                    // VkImage                                      image;
4700                 {                                                                               // VkImageSubresourceRange      subresourceRange;
4701                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags           aspectMask;
4702                         0u,                                                                     // deUint32                                     baseMipLevel;
4703                         1u,                                                                     // deUint32                                     mipLevels;
4704                         0u,                                                                     // deUint32                                     baseArraySlice;
4705                         getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
4706                 }
4707         };
4708
4709         beginCommandBuffer(vk, *m_cmdBuffer);
4710         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);
4711
4712         if (m_params.extensionUse == EXTENSION_USE_NONE)
4713         {
4714                 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());
4715         }
4716         else
4717         {
4718                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4719                 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
4720                 {
4721                         VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,     // VkStructureType                              sType;
4722                         DE_NULL,                                                                        // const void*                                  pNext;
4723                         sourceImage,                                                            // VkImage                                              srcImage;
4724                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                                srcImageLayout;
4725                         m_destination.get(),                                            // VkImage                                              dstImage;
4726                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                                dstImageLayout;
4727                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
4728                         imageResolves2KHR.data()                                        // const  VkImageResolve2KHR*   pRegions;
4729                 };
4730                 vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
4731         }
4732
4733         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);
4734         endCommandBuffer(vk, *m_cmdBuffer);
4735         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4736
4737         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
4738
4739         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
4740         {
4741                 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
4742                 // resolving the image and giving every sample the same value.
4743                 const auto intermediateResult = checkIntermediateCopy();
4744                 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
4745                         return intermediateResult;
4746         }
4747
4748         return checkTestResult(resultTextureLevel->getAccess());
4749 }
4750
4751 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
4752 {
4753         const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel[0]->getAccess();
4754         const float                                                     fuzzyThreshold  = 0.01f;
4755
4756         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
4757         {
4758                 const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
4759                 const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
4760                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
4761                         return tcu::TestStatus::fail("CopiesAndBlitting test");
4762         }
4763
4764         return tcu::TestStatus::pass("CopiesAndBlitting test");
4765 }
4766
4767 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4768 {
4769         DE_UNREF(mipLevel);
4770
4771         VkOffset3D srcOffset    = region.imageResolve.srcOffset;
4772                         srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
4773         VkOffset3D dstOffset    = region.imageResolve.dstOffset;
4774                         dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
4775         VkExtent3D extent               = region.imageResolve.extent;
4776                         extent.depth            = region.imageResolve.srcSubresource.layerCount;
4777
4778         const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
4779         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
4780         const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
4781         const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
4782
4783         tcu::copy(dstSubRegion, srcSubRegion);
4784 }
4785
4786 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
4787 {
4788         const           auto&   vkd                                     = m_context.getDeviceInterface();
4789         const           auto    device                          = m_context.getDevice();
4790         const           auto    queue                           = m_context.getUniversalQueue();
4791         const           auto    queueIndex                      = m_context.getUniversalQueueFamilyIndex();
4792                                 auto&   alloc                           = m_context.getDefaultAllocator();
4793         const           auto    currentLayout           = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4794         const           auto    numDstLayers            = getArraySize(m_params.dst.image);
4795         const           auto    numInputAttachments     = numDstLayers + 1u; // For the source image.
4796         constexpr       auto    numSets                         = 2u; // 1 for the output buffer, 1 for the input attachments.
4797         const           auto    fbWidth                         = m_params.src.image.extent.width;
4798         const           auto    fbHeight                        = m_params.src.image.extent.height;
4799
4800         // Push constants.
4801         const std::array<int, 3> pushConstantData =
4802         {{
4803                 static_cast<int>(fbWidth),
4804                 static_cast<int>(fbHeight),
4805                 static_cast<int>(m_params.samples),
4806         }};
4807         const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
4808
4809         // Shader modules.
4810         const auto vertexModule                 = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
4811         const auto verificationModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
4812
4813         // Descriptor sets.
4814         DescriptorPoolBuilder poolBuilder;
4815         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4816         poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
4817         const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
4818
4819         DescriptorSetLayoutBuilder layoutBuilderBuffer;
4820         layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
4821         const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
4822
4823         DescriptorSetLayoutBuilder layoutBuilderAttachments;
4824         for (deUint32 i = 0u; i < numInputAttachments; ++i)
4825                 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
4826         const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
4827
4828         const auto descriptorSetBuffer          = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
4829         const auto descriptorSetAttachments     = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
4830
4831         // Array with raw descriptor sets.
4832         const std::array<VkDescriptorSet, numSets> descriptorSets =
4833         {{
4834                 descriptorSetBuffer.get(),
4835                 descriptorSetAttachments.get(),
4836         }};
4837
4838         // Pipeline layout.
4839         const std::array<VkDescriptorSetLayout, numSets> setLayouts =
4840         {{
4841                 outputBufferSetLayout.get(),
4842                 inputAttachmentsSetLayout.get(),
4843         }};
4844
4845         const VkPushConstantRange pushConstantRange =
4846         {
4847                 VK_SHADER_STAGE_FRAGMENT_BIT,   //      VkShaderStageFlags      stageFlags;
4848                 0u,                                                             //      deUint32                        offset;
4849                 pushConstantSize,                               //      deUint32                        size;
4850         };
4851
4852         const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
4853         {
4854                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //      VkStructureType                                 sType;
4855                 nullptr,                                                                                //      const void*                                             pNext;
4856                 0u,                                                                                             //      VkPipelineLayoutCreateFlags             flags;
4857                 static_cast<deUint32>(setLayouts.size()),               //      deUint32                                                setLayoutCount;
4858                 setLayouts.data(),                                                              //      const VkDescriptorSetLayout*    pSetLayouts;
4859                 1u,                                                                                             //      deUint32                                                pushConstantRangeCount;
4860                 &pushConstantRange,                                                             //      const VkPushConstantRange*              pPushConstantRanges;
4861         };
4862
4863         const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
4864
4865         // Render pass.
4866         const VkAttachmentDescription commonAttachmentDescription =
4867         {
4868                 0u,                                                                     //      VkAttachmentDescriptionFlags    flags;
4869                 m_params.src.image.format,                      //      VkFormat                                                format;
4870                 m_params.samples,                                       //      VkSampleCountFlagBits                   samples;
4871                 VK_ATTACHMENT_LOAD_OP_LOAD,                     //      VkAttachmentLoadOp                              loadOp;
4872                 VK_ATTACHMENT_STORE_OP_STORE,           //      VkAttachmentStoreOp                             storeOp;
4873                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,        //      VkAttachmentLoadOp                              stencilLoadOp;
4874                 VK_ATTACHMENT_STORE_OP_DONT_CARE,       //      VkAttachmentStoreOp                             stencilStoreOp;
4875                 currentLayout,                                          //      VkImageLayout                                   initialLayout;
4876                 currentLayout,                                          //      VkImageLayout                                   finalLayout;
4877         };
4878         const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
4879
4880         std::vector<VkAttachmentReference> inputAttachmentReferences;
4881         inputAttachmentReferences.reserve(numInputAttachments);
4882         for (deUint32 i = 0u; i < numInputAttachments; ++i)
4883         {
4884                 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
4885                 inputAttachmentReferences.push_back(reference);
4886         }
4887
4888         const VkSubpassDescription subpassDescription =
4889         {
4890                 0u,                                                                                                                     //      VkSubpassDescriptionFlags               flags;
4891                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                                        //      VkPipelineBindPoint                             pipelineBindPoint;
4892                 static_cast<deUint32>(inputAttachmentReferences.size()),        //      deUint32                                                inputAttachmentCount;
4893                 inputAttachmentReferences.data(),                                                       //      const VkAttachmentReference*    pInputAttachments;
4894                 0u,                                                                                                                     //      deUint32                                                colorAttachmentCount;
4895                 nullptr,                                                                                                        //      const VkAttachmentReference*    pColorAttachments;
4896                 nullptr,                                                                                                        //      const VkAttachmentReference*    pResolveAttachments;
4897                 nullptr,                                                                                                        //      const VkAttachmentReference*    pDepthStencilAttachment;
4898                 0u,                                                                                                                     //      deUint32                                                preserveAttachmentCount;
4899                 nullptr,                                                                                                        //      const deUint32*                                 pPreserveAttachments;
4900         };
4901
4902         const VkRenderPassCreateInfo renderPassInfo =
4903         {
4904                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              //      VkStructureType                                 sType;
4905                 nullptr,                                                                                                //      const void*                                             pNext;
4906                 0u,                                                                                                             //      VkRenderPassCreateFlags                 flags;
4907                 static_cast<deUint32>(attachmentDescriptions.size()),   //      deUint32                                                attachmentCount;
4908                 attachmentDescriptions.data(),                                                  //      const VkAttachmentDescription*  pAttachments;
4909                 1u,                                                                                                             //      deUint32                                                subpassCount;
4910                 &subpassDescription,                                                                    //      const VkSubpassDescription*             pSubpasses;
4911                 0u,                                                                                                             //      deUint32                                                dependencyCount;
4912                 nullptr,                                                                                                //      const VkSubpassDependency*              pDependencies;
4913         };
4914
4915         const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
4916
4917         // Framebuffer.
4918         std::vector<Move<VkImageView>>  imageViews;
4919         std::vector<VkImageView>                imageViewsRaw;
4920
4921         imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
4922         for (deUint32 i = 0u; i < numDstLayers; ++i)
4923         {
4924                 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
4925                 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
4926         }
4927
4928         imageViewsRaw.reserve(imageViews.size());
4929         std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
4930
4931         const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
4932
4933         // Storage buffer.
4934         const auto                      bufferCount     = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
4935         const auto                      bufferSize      = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
4936         BufferWithMemory        buffer          (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
4937         auto&                           bufferAlloc     = buffer.getAllocation();
4938         void*                           bufferData      = bufferAlloc.getHostPtr();
4939
4940         // Update descriptor sets.
4941         DescriptorSetUpdateBuilder updater;
4942
4943         const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
4944         updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
4945
4946         std::vector<VkDescriptorImageInfo> imageInfos;
4947         imageInfos.reserve(imageViewsRaw.size());
4948         for (size_t i = 0; i < imageViewsRaw.size(); ++i)
4949                 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
4950
4951         for (size_t i = 0; i < imageInfos.size(); ++i)
4952                 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
4953
4954         updater.update(vkd, device);
4955
4956         // Vertex buffer.
4957         std::vector<tcu::Vec4> fullScreenQuad;
4958         {
4959                 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
4960                 const tcu::Vec4 topLeft         (-1.0f, -1.0f, 0.0f, 1.0f);
4961                 const tcu::Vec4 topRight        ( 1.0f, -1.0f, 0.0f, 1.0f);
4962                 const tcu::Vec4 bottomLeft      (-1.0f,  1.0f, 0.0f, 1.0f);
4963                 const tcu::Vec4 bottomRight     ( 1.0f,  1.0f, 0.0f, 1.0f);
4964
4965                 fullScreenQuad.reserve(6u);
4966                 fullScreenQuad.push_back(topLeft);
4967                 fullScreenQuad.push_back(topRight);
4968                 fullScreenQuad.push_back(bottomRight);
4969                 fullScreenQuad.push_back(topLeft);
4970                 fullScreenQuad.push_back(bottomRight);
4971                 fullScreenQuad.push_back(bottomLeft);
4972         }
4973
4974         const auto                              vertexBufferSize        = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
4975         const auto                              vertexBufferInfo        = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
4976         const BufferWithMemory  vertexBuffer            (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
4977         const auto                              vertexBufferHandler     = vertexBuffer.get();
4978         auto&                                   vertexBufferAlloc       = vertexBuffer.getAllocation();
4979         void*                                   vertexBufferData        = vertexBufferAlloc.getHostPtr();
4980         const VkDeviceSize              vertexBufferOffset      = 0ull;
4981
4982         deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
4983         flushAlloc(vkd, device, vertexBufferAlloc);
4984
4985         // Graphics pipeline.
4986         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
4987         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
4988
4989         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
4990         {
4991                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
4992                 nullptr,                                                                                                        // const void*                                                          pNext;
4993                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
4994                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
4995                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
4996                 0.0f,                                                                                                           // float                                                                        minSampleShading;
4997                 nullptr,                                                                                                        // const VkSampleMask*                                          pSampleMask;
4998                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
4999                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
5000         };
5001
5002         const auto graphicsPipeline = makeGraphicsPipeline(
5003                 vkd,                                                                    // const DeviceInterface&                        vk
5004                 device,                                                                 // const VkDevice                                device
5005                 pipelineLayout.get(),                                   // const VkPipelineLayout                        pipelineLayout
5006                 vertexModule.get(),                                             // const VkShaderModule                          vertexShaderModule
5007                 DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
5008                 DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
5009                 DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
5010                 verificationModule.get(),                               // const VkShaderModule                          fragmentShaderModule
5011                 renderPass.get(),                                               // const VkRenderPass                            renderPass
5012                 viewports,                                                              // const std::vector<VkViewport>&                viewports
5013                 scissors,                                                               // const std::vector<VkRect2D>&                  scissors
5014                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
5015                 0u,                                                                             // const deUint32                                subpass
5016                 0u,                                                                             // const deUint32                                patchControlPoints
5017                 nullptr,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
5018                 nullptr,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5019                 &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
5020
5021         // Command buffer.
5022         const auto cmdPool              = makeCommandPool(vkd, device, queueIndex);
5023         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5024         const auto cmdBuffer    = cmdBufferPtr.get();
5025
5026         // Make sure multisample copy data is available to the fragment shader.
5027         const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
5028
5029         // Make sure verification buffer data is available on the host.
5030         const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
5031
5032         // Record and submit command buffer.
5033         beginCommandBuffer(vkd, cmdBuffer);
5034         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
5035         beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
5036         vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
5037         vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
5038         vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
5039         vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
5040         vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
5041         endRenderPass(vkd, cmdBuffer);
5042         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
5043         endCommandBuffer(vkd, cmdBuffer);
5044         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
5045
5046         // Verify intermediate results.
5047         invalidateAlloc(vkd, device, bufferAlloc);
5048         std::vector<deInt32> outputFlags (bufferCount, 0);
5049         deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
5050
5051         auto& log = m_context.getTestContext().getLog();
5052         log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
5053
5054         const auto sampleCount = static_cast<deUint32>(m_params.samples);
5055
5056         for (deUint32 x = 0u; x < fbWidth; ++x)
5057         for (deUint32 y = 0u; y < fbHeight; ++y)
5058         for (deUint32 s = 0u; s < sampleCount; ++s)
5059         {
5060                 const auto index = (y * fbWidth + x) * sampleCount + s;
5061                 if (!outputFlags[index])
5062                 {
5063                         std::ostringstream msg;
5064                         msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
5065                         return tcu::TestStatus::fail(msg.str());
5066                 }
5067         }
5068
5069         log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
5070         return tcu::TestStatus::pass("Pass");
5071 }
5072
5073 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
5074 {
5075         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
5076         const VkDevice                                  vkDevice                        = m_context.getDevice();
5077         const VkQueue                                   queue                           = m_context.getUniversalQueue();
5078         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
5079         std::vector<VkImageCopy>                imageCopies;
5080         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
5081
5082         for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
5083         {
5084                 const VkImageSubresourceLayers  sourceSubresourceLayers =
5085                 {
5086                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
5087                         0u,                                                             // deUint32                             mipLevel;
5088                         0u,                                                             // deUint32                             baseArrayLayer;
5089                         1u                                                              // deUint32                             layerCount;
5090                 };
5091
5092                 const VkImageSubresourceLayers  destinationSubresourceLayers    =
5093                 {
5094                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
5095                         0u,                                                             // deUint32                             mipLevel;
5096                         layerNdx,                                               // deUint32                             baseArrayLayer;
5097                         1u                                                              // deUint32                             layerCount;
5098                 };
5099
5100                 const VkImageCopy                               imageCopy       =
5101                 {
5102                         sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
5103                         {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
5104                         destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
5105                         {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
5106                          getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
5107                 };
5108
5109                 if (m_params.extensionUse == EXTENSION_USE_NONE)
5110                 {
5111                         imageCopies.push_back(imageCopy);
5112                 }
5113                 else
5114                 {
5115                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5116                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
5117                 }
5118         }
5119
5120         const VkImageMemoryBarrier              imageBarriers[]         =
5121         {
5122                 // source image
5123                 {
5124                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5125                         DE_NULL,                                                                        // const void*                          pNext;
5126                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
5127                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
5128                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
5129                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
5130                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5131                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5132                         m_multisampledImage.get(),                                      // VkImage                                      image;
5133                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5134                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
5135                                 0u,                                                                     // deUint32                             baseMipLevel;
5136                                 1u,                                                                     // deUint32                             mipLevels;
5137                                 0u,                                                                     // deUint32                             baseArraySlice;
5138                                 getArraySize(m_params.src.image)        // deUint32                             arraySize;
5139                         }
5140                 },
5141                 // destination image
5142                 {
5143                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5144                         DE_NULL,                                                                        // const void*                          pNext;
5145                         0,                                                                                      // VkAccessFlags                        srcAccessMask;
5146                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
5147                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
5148                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
5149                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5150                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5151                         m_multisampledCopyImage.get(),                          // VkImage                                      image;
5152                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5153                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
5154                                 0u,                                                                     // deUint32                             baseMipLevel;
5155                                 1u,                                                                     // deUint32                             mipLevels;
5156                                 0u,                                                                     // deUint32                             baseArraySlice;
5157                                 copyArraySize                                           // deUint32                             arraySize;
5158                         }
5159                 },
5160         };
5161
5162         const VkImageMemoryBarrier      postImageBarriers               =
5163         // destination image
5164         {
5165                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5166                 DE_NULL,                                                                        // const void*                          pNext;
5167                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
5168                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
5169                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
5170                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
5171                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5172                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5173                 m_multisampledCopyImage.get(),                          // VkImage                                      image;
5174                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
5175                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
5176                         0u,                                                                     // deUint32                             baseMipLevel;
5177                         1u,                                                                     // deUint32                             mipLevels;
5178                         0u,                                                                     // deUint32                             baseArraySlice;
5179                         copyArraySize                                           // deUint32                             arraySize;
5180                 }
5181         };
5182
5183         beginCommandBuffer(vk, *m_cmdBuffer);
5184         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);
5185
5186         if (m_params.extensionUse == EXTENSION_USE_NONE)
5187         {
5188                 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());
5189         }
5190         else
5191         {
5192                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5193                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
5194                 {
5195                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
5196                         DE_NULL,                                                                        // const void*                          pNext;
5197                         m_multisampledImage.get(),                                      // VkImage                                      srcImage;
5198                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        srcImageLayout;
5199                         m_multisampledCopyImage.get(),                          // VkImage                                      dstImage;
5200                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        dstImageLayout;
5201                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
5202                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
5203                 };
5204
5205                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
5206         }
5207
5208         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);
5209         endCommandBuffer(vk, *m_cmdBuffer);
5210
5211         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
5212 }
5213
5214 class ResolveImageToImageTestCase : public vkt::TestCase
5215 {
5216 public:
5217                                                         ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
5218                                                                                                                  const std::string&                                     name,
5219                                                                                                                  const std::string&                                     description,
5220                                                                                                                  const TestParams                                       params,
5221                                                                                                                  const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
5222                                                                 : vkt::TestCase (testCtx, name, description)
5223                                                                 , m_params              (params)
5224                                                                 , m_options             (options)
5225         {}
5226
5227                                                         virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
5228
5229         virtual TestInstance*   createInstance                          (Context&                               context) const
5230         {
5231                 return new ResolveImageToImage(context, m_params, m_options);
5232         }
5233
5234         virtual void                    checkSupport                            (Context&                               context) const
5235         {
5236                 const VkSampleCountFlagBits     rasterizationSamples = m_params.samples;
5237
5238                 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
5239                         throw tcu::NotSupportedError("Unsupported number of rasterization samples");
5240
5241                 VkImageFormatProperties properties;
5242                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5243                                                                                                                                                                         m_params.src.image.format,
5244                                                                                                                                                                         m_params.src.image.imageType,
5245                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
5246                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
5247                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
5248                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5249                                                                                                                                                                         m_params.dst.image.format,
5250                                                                                                                                                                         m_params.dst.image.imageType,
5251                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
5252                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
5253                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
5254                 {
5255                         TCU_THROW(NotSupportedError, "Format not supported");
5256                 }
5257
5258                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)     &&
5259                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5260                 {
5261                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5262                 }
5263         }
5264
5265 private:
5266         TestParams                                                      m_params;
5267         const ResolveImageToImageOptions        m_options;
5268 };
5269
5270 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
5271 {
5272         programCollection.glslSources.add("vert") << glu::VertexSource(
5273                 "#version 310 es\n"
5274                 "layout (location = 0) in highp vec4 a_position;\n"
5275                 "void main()\n"
5276                 "{\n"
5277                 "       gl_Position = a_position;\n"
5278                 "}\n");
5279
5280
5281         programCollection.glslSources.add("frag") << glu::FragmentSource(
5282                 "#version 310 es\n"
5283                 "layout (location = 0) out highp vec4 o_color;\n"
5284                 "void main()\n"
5285                 "{\n"
5286                 "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5287                 "}\n");
5288
5289         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
5290         {
5291                 // The shader verifies all layers in the copied image are the same as the source image.
5292                 // This needs an image view per layer in the copied image.
5293                 // Set 0 contains the output buffer.
5294                 // Set 1 contains the input attachments.
5295
5296                 std::ostringstream verificationShader;
5297
5298                 verificationShader
5299                         << "#version 450\n"
5300                         << "\n"
5301                         << "layout (push_constant, std430) uniform PushConstants {\n"
5302                         << "    int width;\n"
5303                         << "    int height;\n"
5304                         << "    int samples;\n"
5305                         << "};\n"
5306                         << "layout (set=0, binding=0) buffer VerificationResults {\n"
5307                         << "    int verificationFlags[];\n"
5308                         << "};\n"
5309                         << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
5310                         ;
5311
5312                 const auto dstLayers = getArraySize(m_params.dst.image);
5313                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
5314                 {
5315                         const auto i = layerNdx + 1u;
5316                         verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
5317                 }
5318
5319                 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
5320                 // created with a single sample.
5321                 verificationShader
5322                         << "\n"
5323                         << "void main() {\n"
5324                         << "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
5325                         << "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
5326                         ;
5327
5328                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
5329                 {
5330                         const auto i = layerNdx + 1u;
5331                         verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
5332                 }
5333
5334                 std::ostringstream testCondition;
5335                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
5336                 {
5337                         const auto i = layerNdx + 1u;
5338                         testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
5339                 }
5340
5341                 verificationShader
5342                         << "\n"
5343                         << "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
5344                         << "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
5345                         << "\n"
5346                         << "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
5347                         << "    }\n"
5348                         << "}\n"
5349                         ;
5350
5351                 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
5352         }
5353 }
5354
5355 struct BufferOffsetParams
5356 {
5357         static constexpr deUint32 kMaxOffset = 8u;
5358
5359         deUint32 srcOffset;
5360         deUint32 dstOffset;
5361 };
5362
5363 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
5364 {
5365         constexpr deUint8 zero{0};
5366         for (deUint32 i = 0; i < count; ++i)
5367         {
5368                 const auto& val = bufferData[from + i];
5369                 if (val != zero)
5370                 {
5371                         std::ostringstream msg;
5372                         msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
5373                         TCU_FAIL(msg.str());
5374                 }
5375         }
5376 }
5377
5378 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
5379 {
5380         // Try to copy blocks of sizes 1 to kMaxOffset. Each copy region will use a block of kMaxOffset*2 bytes to take into account srcOffset and dstOffset.
5381         constexpr auto kMaxOffset       = BufferOffsetParams::kMaxOffset;
5382         constexpr auto kBlockSize       = kMaxOffset * 2u;
5383         constexpr auto kBufferSize      = kMaxOffset * kBlockSize;
5384
5385         DE_ASSERT(params.srcOffset < kMaxOffset);
5386         DE_ASSERT(params.dstOffset < kMaxOffset);
5387
5388         const auto&     vkd             = ctx.getDeviceInterface();
5389         const auto      device  = ctx.getDevice();
5390         auto&           alloc   = ctx.getDefaultAllocator();
5391         const auto      qIndex  = ctx.getUniversalQueueFamilyIndex();
5392         const auto      queue   = ctx.getUniversalQueue();
5393
5394         const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
5395         const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
5396
5397         BufferWithMemory        srcBuffer       (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
5398         BufferWithMemory        dstBuffer       (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
5399         auto&                           srcAlloc        = srcBuffer.getAllocation();
5400         auto&                           dstAlloc        = dstBuffer.getAllocation();
5401
5402         // Zero-out destination buffer.
5403         deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
5404         flushAlloc(vkd, device, dstAlloc);
5405
5406         // Fill source buffer with nonzero bytes.
5407         std::vector<deUint8> srcData;
5408         srcData.reserve(kBufferSize);
5409         for (deUint32 i = 0; i < kBufferSize; ++i)
5410                 srcData.push_back(static_cast<deUint8>(100u + i));
5411         deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
5412         flushAlloc(vkd, device, srcAlloc);
5413
5414         // Copy regions.
5415         std::vector<VkBufferCopy> copies;
5416         copies.reserve(kMaxOffset);
5417         for (deUint32 i = 0; i < kMaxOffset; ++i)
5418         {
5419                 const auto blockStart   = kBlockSize * i;
5420                 const auto copySize             = i + 1u;
5421                 const auto bufferCopy   = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
5422                 copies.push_back(bufferCopy);
5423         }
5424
5425         const auto cmdPool              = makeCommandPool(vkd, device, qIndex);
5426         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5427         const auto cmdBuffer    = cmdBufferPtr.get();
5428
5429         beginCommandBuffer(vkd, cmdBuffer);
5430         vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
5431         const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
5432         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
5433         endCommandBuffer(vkd, cmdBuffer);
5434         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
5435         invalidateAlloc(vkd, device, dstAlloc);
5436
5437         // Verify destination buffer data.
5438         std::vector<deUint8> dstData(kBufferSize);
5439         deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
5440
5441         for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
5442         {
5443                 const auto blockStart   = kBlockSize * blockIdx;
5444                 const auto copySize             = blockIdx + 1u;
5445
5446                 // Verify no data has been written before dstOffset.
5447                 checkZerosAt(dstData, blockStart, params.dstOffset);
5448
5449                 // Verify copied block.
5450                 for (deUint32 i = 0; i < copySize; ++i)
5451                 {
5452                         const auto& dstVal = dstData[blockStart + params.dstOffset + i];
5453                         const auto& srcVal = srcData[blockStart + params.srcOffset + i];
5454                         if (dstVal != srcVal)
5455                         {
5456                                 std::ostringstream msg;
5457                                 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
5458                                 TCU_FAIL(msg.str());
5459                         }
5460                 }
5461
5462                 // Verify no data has been written after copy block.
5463                 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
5464         }
5465
5466         return tcu::TestStatus::pass("Pass");
5467 }
5468
5469 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
5470 {
5471         return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
5472 }
5473
5474 std::string getFormatCaseName (VkFormat format)
5475 {
5476         return de::toLower(de::toString(getFormatStr(format)).substr(10));
5477 }
5478
5479 std::string getImageLayoutCaseName (VkImageLayout layout)
5480 {
5481         switch (layout)
5482         {
5483                 case VK_IMAGE_LAYOUT_GENERAL:
5484                         return "general";
5485                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
5486                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
5487                         return "optimal";
5488                 default:
5489                         DE_ASSERT(false);
5490                         return "";
5491         }
5492 }
5493
5494 const deInt32                                   defaultSize                             = 64;
5495 const deInt32                                   defaultHalfSize                 = defaultSize / 2;
5496 const deInt32                                   defaultFourthSize               = defaultSize / 4;
5497 const deInt32                                   defaultSixteenthSize    = defaultSize / 16;
5498 const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
5499 const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
5500 const VkExtent3D                                default1dExtent                 = {defaultSize, 1, 1};
5501 const VkExtent3D                                default3dExtent                 = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
5502
5503 const VkImageSubresourceLayers  defaultSourceLayer              =
5504 {
5505         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
5506         0u,                                                     // deUint32                             mipLevel;
5507         0u,                                                     // deUint32                             baseArrayLayer;
5508         1u,                                                     // deUint32                             layerCount;
5509 };
5510
5511 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
5512 {
5513         tcu::TestContext& testCtx       = group->getTestContext();
5514
5515         {
5516                 TestParams      params;
5517                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5518                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
5519                 params.src.image.extent                         = defaultExtent;
5520                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5521                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5522                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5523                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
5524                 params.dst.image.extent                         = defaultExtent;
5525                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5526                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5527                 params.allocationKind                           = allocationKind;
5528                 params.extensionUse                                     = extensionUse;
5529
5530                 {
5531                         const VkImageCopy                               testCopy        =
5532                         {
5533                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5534                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
5535                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5536                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
5537                                 defaultExtent,          // VkExtent3D                           extent;
5538                         };
5539
5540                         CopyRegion      imageCopy;
5541                         imageCopy.imageCopy     = testCopy;
5542                         params.regions.push_back(imageCopy);
5543                 }
5544
5545                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
5546         }
5547
5548         {
5549                 TestParams      params;
5550                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5551                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
5552                 params.src.image.extent                         = defaultExtent;
5553                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5554                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5555                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5556                 params.dst.image.format                         = VK_FORMAT_R32_UINT;
5557                 params.dst.image.extent                         = defaultExtent;
5558                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5559                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5560                 params.allocationKind                           = allocationKind;
5561                 params.extensionUse                                     = extensionUse;
5562
5563                 {
5564                         const VkImageCopy                               testCopy        =
5565                         {
5566                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5567                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
5568                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5569                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
5570                                 defaultExtent,          // VkExtent3D                           extent;
5571                         };
5572
5573                         CopyRegion      imageCopy;
5574                         imageCopy.imageCopy = testCopy;
5575                         params.regions.push_back(imageCopy);
5576                 }
5577
5578                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
5579         }
5580
5581         {
5582                 TestParams      params;
5583                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5584                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
5585                 params.src.image.extent                         = defaultExtent;
5586                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5587                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5588                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5589                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
5590                 params.dst.image.extent                         = defaultExtent;
5591                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5592                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5593                 params.allocationKind                           = allocationKind;
5594                 params.extensionUse                                     = extensionUse;
5595
5596                 {
5597                         const VkImageCopy                               testCopy        =
5598                         {
5599                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     srcSubresource;
5600                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
5601                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     dstSubresource;
5602                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
5603                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
5604                         };
5605
5606                         CopyRegion      imageCopy;
5607                         imageCopy.imageCopy = testCopy;
5608                         params.regions.push_back(imageCopy);
5609                 }
5610
5611                 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
5612         }
5613
5614         static const struct
5615         {
5616                 std::string             name;
5617                 vk::VkFormat    format1;
5618                 vk::VkFormat    format2;
5619         } formats [] =
5620         {
5621                 { "diff_format",        vk::VK_FORMAT_R32_UINT,                 vk::VK_FORMAT_R8G8B8A8_UNORM    },
5622                 { "same_format",        vk::VK_FORMAT_R8G8B8A8_UNORM,   vk::VK_FORMAT_R8G8B8A8_UNORM    }
5623         };
5624         static const struct
5625         {
5626                 std::string             name;
5627                 vk::VkBool32    clear;
5628         } clears [] =
5629         {
5630                 { "clear",              VK_TRUE         },
5631                 { "noclear",    VK_FALSE        }
5632         };
5633         static const struct
5634         {
5635                 std::string             name;
5636                 VkExtent3D              extent;
5637         } extents [] =
5638         {
5639                 { "npot",       {65u, 63u, 1u}  },
5640                 { "pot",        {64u, 64u, 1u}  }
5641         };
5642
5643         for (const auto& format : formats)
5644         {
5645                 for (const auto& clear : clears)
5646                 {
5647                         for (const auto& extent : extents)
5648                         {
5649                                 TestParams      params;
5650                                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5651                                 params.src.image.format                         = format.format1;
5652                                 params.src.image.extent                         = extent.extent;
5653                                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5654                                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5655                                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5656                                 params.dst.image.format                         = format.format2;
5657                                 params.dst.image.extent                         = extent.extent;
5658                                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5659                                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5660                                 params.allocationKind                           = allocationKind;
5661                                 params.extensionUse                                     = extensionUse;
5662                                 params.clearDestination                         = clear.clear;
5663
5664                                 {
5665                                         VkImageCopy     testCopy        =
5666                                         {
5667                                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
5668                                                 {34, 34, 0},            // VkOffset3D                           srcOffset;
5669                                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
5670                                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
5671                                                 {31, 29, 1}                     // VkExtent3D                           extent;
5672                                         };
5673
5674                                         if (extent.name == "pot")
5675                                         {
5676                                                 testCopy.srcOffset      = { 16, 16, 0 };
5677                                                 testCopy.extent         = { 32, 32, 1 };
5678                                         }
5679
5680                                         CopyRegion      imageCopy;
5681                                         imageCopy.imageCopy = testCopy;
5682                                         params.regions.push_back(imageCopy);
5683                                 }
5684
5685                                 // Example test case name: "partial_image_npot_diff_format_clear"
5686                                 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
5687
5688                                 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
5689                         }
5690                 }
5691         }
5692
5693         {
5694                 TestParams      params;
5695                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5696                 params.src.image.format                         = VK_FORMAT_D32_SFLOAT;
5697                 params.src.image.extent                         = defaultExtent;
5698                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5699                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5700                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5701                 params.dst.image.format                         = VK_FORMAT_D32_SFLOAT;
5702                 params.dst.image.extent                         = defaultExtent;
5703                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5704                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5705                 params.allocationKind                           = allocationKind;
5706                 params.extensionUse                                     = extensionUse;
5707
5708                 {
5709                         const VkImageSubresourceLayers  sourceLayer =
5710                         {
5711                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
5712                                 0u,                                                     // deUint32                             mipLevel;
5713                                 0u,                                                     // deUint32                             baseArrayLayer;
5714                                 1u                                                      // deUint32                             layerCount;
5715                         };
5716                         const VkImageCopy                               testCopy        =
5717                         {
5718                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
5719                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
5720                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
5721                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
5722                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
5723                         };
5724
5725                         CopyRegion      imageCopy;
5726                         imageCopy.imageCopy = testCopy;
5727                         params.regions.push_back(imageCopy);
5728                 }
5729
5730                 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
5731         }
5732
5733         {
5734                 TestParams      params;
5735                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
5736                 params.src.image.format                         = VK_FORMAT_S8_UINT;
5737                 params.src.image.extent                         = defaultExtent;
5738                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5739                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5740                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
5741                 params.dst.image.format                         = VK_FORMAT_S8_UINT;
5742                 params.dst.image.extent                         = defaultExtent;
5743                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
5744                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5745                 params.allocationKind                           = allocationKind;
5746                 params.extensionUse                                     = extensionUse;
5747
5748                 {
5749                         const VkImageSubresourceLayers  sourceLayer =
5750                         {
5751                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
5752                                 0u,                                                             // deUint32                             mipLevel;
5753                                 0u,                                                             // deUint32                             baseArrayLayer;
5754                                 1u                                                              // deUint32                             layerCount;
5755                         };
5756                         const VkImageCopy                               testCopy        =
5757                         {
5758                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
5759                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
5760                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
5761                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
5762                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
5763                         };
5764
5765                         CopyRegion      imageCopy;
5766                         imageCopy.imageCopy = testCopy;
5767                         params.regions.push_back(imageCopy);
5768                 }
5769
5770                 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
5771         }
5772 }
5773
5774 struct CopyColorTestParams
5775 {
5776         TestParams              params;
5777         const VkFormat* compatibleFormats;
5778 };
5779
5780 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
5781 {
5782         const VkImageLayout copySrcLayouts[]            =
5783         {
5784                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5785                 VK_IMAGE_LAYOUT_GENERAL
5786         };
5787         const VkImageLayout copyDstLayouts[]            =
5788         {
5789                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5790                 VK_IMAGE_LAYOUT_GENERAL
5791         };
5792
5793         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
5794         {
5795                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
5796
5797                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
5798                 {
5799                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
5800
5801                         const std::string testName      = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
5802                                                                                   getImageLayoutCaseName(params.dst.image.operationLayout);
5803                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
5804                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
5805                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
5806                 }
5807         }
5808 }
5809
5810 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
5811 {
5812         bool result = true;
5813
5814         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
5815         {
5816                 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
5817
5818                 result =
5819                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
5820                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
5821         }
5822
5823         return result;
5824 }
5825
5826 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
5827 {
5828         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
5829         const VkFormat  srcFormatOnly[2]        = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
5830         const VkFormat* formatList                      = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
5831
5832         for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
5833         {
5834                 testParams.params.dst.image.format = formatList[dstFormatIndex];
5835
5836                 const VkFormat          srcFormat       = testParams.params.src.image.format;
5837                 const VkFormat          dstFormat       = testParams.params.dst.image.format;
5838
5839                 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
5840                         continue;
5841
5842                 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
5843                         continue;
5844
5845                 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
5846                         if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
5847                                 continue;
5848
5849                 const std::string       description     = "Copy to destination format " + getFormatCaseName(dstFormat);
5850                 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
5851         }
5852 }
5853
5854 const VkFormat  compatibleFormats8Bit[]         =
5855 {
5856         VK_FORMAT_R4G4_UNORM_PACK8,
5857         VK_FORMAT_R8_UNORM,
5858         VK_FORMAT_R8_SNORM,
5859         VK_FORMAT_R8_USCALED,
5860         VK_FORMAT_R8_SSCALED,
5861         VK_FORMAT_R8_UINT,
5862         VK_FORMAT_R8_SINT,
5863         VK_FORMAT_R8_SRGB,
5864
5865         VK_FORMAT_UNDEFINED
5866 };
5867 const VkFormat  compatibleFormats16Bit[]        =
5868 {
5869         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
5870         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
5871         VK_FORMAT_R5G6B5_UNORM_PACK16,
5872         VK_FORMAT_B5G6R5_UNORM_PACK16,
5873         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
5874         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
5875         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
5876         VK_FORMAT_R8G8_UNORM,
5877         VK_FORMAT_R8G8_SNORM,
5878         VK_FORMAT_R8G8_USCALED,
5879         VK_FORMAT_R8G8_SSCALED,
5880         VK_FORMAT_R8G8_UINT,
5881         VK_FORMAT_R8G8_SINT,
5882         VK_FORMAT_R8G8_SRGB,
5883         VK_FORMAT_R16_UNORM,
5884         VK_FORMAT_R16_SNORM,
5885         VK_FORMAT_R16_USCALED,
5886         VK_FORMAT_R16_SSCALED,
5887         VK_FORMAT_R16_UINT,
5888         VK_FORMAT_R16_SINT,
5889         VK_FORMAT_R16_SFLOAT,
5890         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
5891         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
5892
5893         VK_FORMAT_UNDEFINED
5894 };
5895 const VkFormat  compatibleFormats24Bit[]        =
5896 {
5897         VK_FORMAT_R8G8B8_UNORM,
5898         VK_FORMAT_R8G8B8_SNORM,
5899         VK_FORMAT_R8G8B8_USCALED,
5900         VK_FORMAT_R8G8B8_SSCALED,
5901         VK_FORMAT_R8G8B8_UINT,
5902         VK_FORMAT_R8G8B8_SINT,
5903         VK_FORMAT_R8G8B8_SRGB,
5904         VK_FORMAT_B8G8R8_UNORM,
5905         VK_FORMAT_B8G8R8_SNORM,
5906         VK_FORMAT_B8G8R8_USCALED,
5907         VK_FORMAT_B8G8R8_SSCALED,
5908         VK_FORMAT_B8G8R8_UINT,
5909         VK_FORMAT_B8G8R8_SINT,
5910         VK_FORMAT_B8G8R8_SRGB,
5911
5912         VK_FORMAT_UNDEFINED
5913 };
5914 const VkFormat  compatibleFormats32Bit[]        =
5915 {
5916         VK_FORMAT_R8G8B8A8_UNORM,
5917         VK_FORMAT_R8G8B8A8_SNORM,
5918         VK_FORMAT_R8G8B8A8_USCALED,
5919         VK_FORMAT_R8G8B8A8_SSCALED,
5920         VK_FORMAT_R8G8B8A8_UINT,
5921         VK_FORMAT_R8G8B8A8_SINT,
5922         VK_FORMAT_R8G8B8A8_SRGB,
5923         VK_FORMAT_B8G8R8A8_UNORM,
5924         VK_FORMAT_B8G8R8A8_SNORM,
5925         VK_FORMAT_B8G8R8A8_USCALED,
5926         VK_FORMAT_B8G8R8A8_SSCALED,
5927         VK_FORMAT_B8G8R8A8_UINT,
5928         VK_FORMAT_B8G8R8A8_SINT,
5929         VK_FORMAT_B8G8R8A8_SRGB,
5930         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
5931         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
5932         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
5933         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
5934         VK_FORMAT_A8B8G8R8_UINT_PACK32,
5935         VK_FORMAT_A8B8G8R8_SINT_PACK32,
5936         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5937         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
5938         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
5939         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
5940         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
5941         VK_FORMAT_A2R10G10B10_UINT_PACK32,
5942         VK_FORMAT_A2R10G10B10_SINT_PACK32,
5943         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
5944         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
5945         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
5946         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
5947         VK_FORMAT_A2B10G10R10_UINT_PACK32,
5948         VK_FORMAT_A2B10G10R10_SINT_PACK32,
5949         VK_FORMAT_R16G16_UNORM,
5950         VK_FORMAT_R16G16_SNORM,
5951         VK_FORMAT_R16G16_USCALED,
5952         VK_FORMAT_R16G16_SSCALED,
5953         VK_FORMAT_R16G16_UINT,
5954         VK_FORMAT_R16G16_SINT,
5955         VK_FORMAT_R16G16_SFLOAT,
5956         VK_FORMAT_R32_UINT,
5957         VK_FORMAT_R32_SINT,
5958         VK_FORMAT_R32_SFLOAT,
5959
5960         VK_FORMAT_UNDEFINED
5961 };
5962 const VkFormat  compatibleFormats48Bit[]        =
5963 {
5964         VK_FORMAT_R16G16B16_UNORM,
5965         VK_FORMAT_R16G16B16_SNORM,
5966         VK_FORMAT_R16G16B16_USCALED,
5967         VK_FORMAT_R16G16B16_SSCALED,
5968         VK_FORMAT_R16G16B16_UINT,
5969         VK_FORMAT_R16G16B16_SINT,
5970         VK_FORMAT_R16G16B16_SFLOAT,
5971
5972         VK_FORMAT_UNDEFINED
5973 };
5974 const VkFormat  compatibleFormats64Bit[]        =
5975 {
5976         VK_FORMAT_R16G16B16A16_UNORM,
5977         VK_FORMAT_R16G16B16A16_SNORM,
5978         VK_FORMAT_R16G16B16A16_USCALED,
5979         VK_FORMAT_R16G16B16A16_SSCALED,
5980         VK_FORMAT_R16G16B16A16_UINT,
5981         VK_FORMAT_R16G16B16A16_SINT,
5982         VK_FORMAT_R16G16B16A16_SFLOAT,
5983         VK_FORMAT_R32G32_UINT,
5984         VK_FORMAT_R32G32_SINT,
5985         VK_FORMAT_R32G32_SFLOAT,
5986         VK_FORMAT_R64_UINT,
5987         VK_FORMAT_R64_SINT,
5988         VK_FORMAT_R64_SFLOAT,
5989
5990         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
5991         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
5992         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
5993         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
5994         VK_FORMAT_BC4_UNORM_BLOCK,
5995         VK_FORMAT_BC4_SNORM_BLOCK,
5996
5997         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
5998         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
5999         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
6000         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
6001
6002         VK_FORMAT_EAC_R11_UNORM_BLOCK,
6003         VK_FORMAT_EAC_R11_SNORM_BLOCK,
6004
6005         VK_FORMAT_UNDEFINED
6006 };
6007 const VkFormat  compatibleFormats96Bit[]        =
6008 {
6009         VK_FORMAT_R32G32B32_UINT,
6010         VK_FORMAT_R32G32B32_SINT,
6011         VK_FORMAT_R32G32B32_SFLOAT,
6012
6013         VK_FORMAT_UNDEFINED
6014 };
6015 const VkFormat  compatibleFormats128Bit[]       =
6016 {
6017         VK_FORMAT_R32G32B32A32_UINT,
6018         VK_FORMAT_R32G32B32A32_SINT,
6019         VK_FORMAT_R32G32B32A32_SFLOAT,
6020         VK_FORMAT_R64G64_UINT,
6021         VK_FORMAT_R64G64_SINT,
6022         VK_FORMAT_R64G64_SFLOAT,
6023
6024         VK_FORMAT_BC2_UNORM_BLOCK,
6025         VK_FORMAT_BC2_SRGB_BLOCK,
6026         VK_FORMAT_BC3_UNORM_BLOCK,
6027         VK_FORMAT_BC3_SRGB_BLOCK,
6028         VK_FORMAT_BC5_UNORM_BLOCK,
6029         VK_FORMAT_BC5_SNORM_BLOCK,
6030         VK_FORMAT_BC6H_UFLOAT_BLOCK,
6031         VK_FORMAT_BC6H_SFLOAT_BLOCK,
6032         VK_FORMAT_BC7_UNORM_BLOCK,
6033         VK_FORMAT_BC7_SRGB_BLOCK,
6034
6035         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
6036         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
6037
6038         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
6039         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
6040
6041         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
6042         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
6043         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
6044         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
6045         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
6046         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
6047         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
6048         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
6049         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
6050         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
6051         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
6052         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
6053         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
6054         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
6055         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
6056         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
6057         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
6058         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
6059         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
6060         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
6061         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
6062         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
6063         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
6064         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
6065         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
6066         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
6067         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
6068         VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
6069
6070         VK_FORMAT_UNDEFINED
6071 };
6072 const VkFormat  compatibleFormats192Bit[]       =
6073 {
6074         VK_FORMAT_R64G64B64_UINT,
6075         VK_FORMAT_R64G64B64_SINT,
6076         VK_FORMAT_R64G64B64_SFLOAT,
6077
6078         VK_FORMAT_UNDEFINED
6079 };
6080 const VkFormat  compatibleFormats256Bit[]       =
6081 {
6082         VK_FORMAT_R64G64B64A64_UINT,
6083         VK_FORMAT_R64G64B64A64_SINT,
6084         VK_FORMAT_R64G64B64A64_SFLOAT,
6085
6086         VK_FORMAT_UNDEFINED
6087 };
6088
6089 const VkFormat* colorImageFormatsToTest[]       =
6090 {
6091         compatibleFormats8Bit,
6092         compatibleFormats16Bit,
6093         compatibleFormats24Bit,
6094         compatibleFormats32Bit,
6095         compatibleFormats48Bit,
6096         compatibleFormats64Bit,
6097         compatibleFormats96Bit,
6098         compatibleFormats128Bit,
6099         compatibleFormats192Bit,
6100         compatibleFormats256Bit
6101 };
6102
6103 const VkFormat  dedicatedAllocationImageToImageFormatsToTest[]  =
6104 {
6105         // From compatibleFormats8Bit
6106         VK_FORMAT_R4G4_UNORM_PACK8,
6107         VK_FORMAT_R8_SRGB,
6108
6109         // From compatibleFormats16Bit
6110         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
6111         VK_FORMAT_R16_SFLOAT,
6112
6113         // From compatibleFormats24Bit
6114         VK_FORMAT_R8G8B8_UNORM,
6115         VK_FORMAT_B8G8R8_SRGB,
6116
6117         // From compatibleFormats32Bit
6118         VK_FORMAT_R8G8B8A8_UNORM,
6119         VK_FORMAT_R32_SFLOAT,
6120
6121         // From compatibleFormats48Bit
6122         VK_FORMAT_R16G16B16_UNORM,
6123         VK_FORMAT_R16G16B16_SFLOAT,
6124
6125         // From compatibleFormats64Bit
6126         VK_FORMAT_R16G16B16A16_UNORM,
6127         VK_FORMAT_R64_SFLOAT,
6128
6129         // From compatibleFormats96Bit
6130         VK_FORMAT_R32G32B32_UINT,
6131         VK_FORMAT_R32G32B32_SFLOAT,
6132
6133         // From compatibleFormats128Bit
6134         VK_FORMAT_R32G32B32A32_UINT,
6135         VK_FORMAT_R64G64_SFLOAT,
6136
6137         // From compatibleFormats192Bit
6138         VK_FORMAT_R64G64B64_UINT,
6139         VK_FORMAT_R64G64B64_SFLOAT,
6140
6141         // From compatibleFormats256Bit
6142         VK_FORMAT_R64G64B64A64_UINT,
6143         VK_FORMAT_R64G64B64A64_SFLOAT,
6144 };
6145
6146 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6147 {
6148         if (allocationKind == ALLOCATION_KIND_DEDICATED)
6149         {
6150                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
6151                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
6152                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
6153         }
6154
6155         // 2D tests.
6156         {
6157                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
6158
6159                 TestParams      params;
6160                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
6161                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
6162                 params.src.image.extent         = defaultExtent;
6163                 params.dst.image.extent         = defaultExtent;
6164                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6165                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6166                 params.allocationKind           = allocationKind;
6167                 params.extensionUse                     = extensionUse;
6168
6169                 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
6170                 {
6171                         const VkImageCopy                               testCopy =
6172                         {
6173                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
6174                                 {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
6175                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
6176                                 {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
6177                                 {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
6178                         };
6179
6180                         CopyRegion      imageCopy;
6181                         imageCopy.imageCopy = testCopy;
6182
6183                         params.regions.push_back(imageCopy);
6184                 }
6185
6186                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
6187                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
6188                 {
6189                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
6190                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
6191                         {
6192                                 params.src.image.format = compatibleFormats[srcFormatIndex];
6193                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
6194                                         continue;
6195
6196                                 CopyColorTestParams     testParams;
6197                                 testParams.params                               = params;
6198                                 testParams.compatibleFormats    = compatibleFormats;
6199
6200                                 const std::string testName              = getFormatCaseName(params.src.image.format);
6201                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
6202                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
6203                         }
6204                 }
6205
6206                 group->addChild(subGroup.release());
6207         }
6208
6209         // 1D tests.
6210         {
6211                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
6212
6213                 TestParams      params;
6214                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
6215                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
6216                 params.src.image.extent         = default1dExtent;
6217                 params.dst.image.extent         = default1dExtent;
6218                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6219                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6220                 params.allocationKind           = allocationKind;
6221                 params.extensionUse                     = extensionUse;
6222
6223                 for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
6224                 {
6225                         const VkImageCopy                               testCopy =
6226                         {
6227                                 defaultSourceLayer,                     // VkImageSubresourceLayers     srcSubresource;
6228                                 {0, 0, 0},                                      // VkOffset3D                           srcOffset;
6229                                 defaultSourceLayer,                     // VkImageSubresourceLayers     dstSubresource;
6230                                 {i, 0, 0},                                      // VkOffset3D                           dstOffset;
6231                                 {defaultFourthSize, 1, 1},      // VkExtent3D                           extent;
6232                         };
6233
6234                         CopyRegion      imageCopy;
6235                         imageCopy.imageCopy = testCopy;
6236
6237                         params.regions.push_back(imageCopy);
6238                 }
6239
6240                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
6241                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
6242                 {
6243                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
6244                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
6245                         {
6246                                 params.src.image.format = compatibleFormats[srcFormatIndex];
6247                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
6248                                         continue;
6249
6250                                 CopyColorTestParams     testParams;
6251                                 testParams.params                               = params;
6252                                 testParams.compatibleFormats    = nullptr;
6253
6254                                 const std::string testName              = getFormatCaseName(params.src.image.format);
6255                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
6256                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
6257                         }
6258                 }
6259
6260                 group->addChild(subGroup.release());
6261         }
6262
6263         // 3D tests. Note we use smaller dimensions here for performance reasons.
6264         {
6265                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
6266
6267                 TestParams      params;
6268                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
6269                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
6270                 params.src.image.extent         = default3dExtent;
6271                 params.dst.image.extent         = default3dExtent;
6272                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6273                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
6274                 params.allocationKind           = allocationKind;
6275                 params.extensionUse                     = extensionUse;
6276
6277                 for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
6278                 {
6279                         const VkImageCopy                               testCopy =
6280                         {
6281                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     srcSubresource;
6282                                 {0, 0, 0},                                                                                                                      // VkOffset3D                           srcOffset;
6283                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     dstSubresource;
6284                                 {i, defaultFourthSize - i - defaultSixteenthSize, i},                           // VkOffset3D                           dstOffset;
6285                                 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},     // VkExtent3D                           extent;
6286                         };
6287
6288                         CopyRegion      imageCopy;
6289                         imageCopy.imageCopy = testCopy;
6290
6291                         params.regions.push_back(imageCopy);
6292                 }
6293
6294                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
6295                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
6296                 {
6297                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
6298                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
6299                         {
6300                                 params.src.image.format = compatibleFormats[srcFormatIndex];
6301                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
6302                                         continue;
6303
6304                                 CopyColorTestParams     testParams;
6305                                 testParams.params                               = params;
6306                                 testParams.compatibleFormats    = nullptr;
6307
6308                                 const std::string testName              = getFormatCaseName(params.src.image.format);
6309                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
6310                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
6311                         }
6312                 }
6313
6314                 group->addChild(subGroup.release());
6315         }
6316 }
6317
6318 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6319 {
6320         tcu::TestContext&               testCtx                         = group->getTestContext();
6321
6322         const VkFormat                  testFormats[][2]        =
6323         {
6324                 // From compatibleFormats8Bit
6325                 {
6326                         VK_FORMAT_R4G4_UNORM_PACK8,
6327                         VK_FORMAT_R8_SRGB
6328                 },
6329                 // From compatibleFormats16Bit
6330                 {
6331                         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
6332                         VK_FORMAT_R16_SFLOAT,
6333                 },
6334                 // From compatibleFormats24Bit
6335                 {
6336                         VK_FORMAT_R8G8B8_UNORM,
6337                         VK_FORMAT_B8G8R8_SRGB
6338                 },
6339                 // From compatibleFormats32Bit
6340                 {
6341                         VK_FORMAT_R8G8B8A8_UNORM,
6342                         VK_FORMAT_R32_SFLOAT
6343                 },
6344                 // From compatibleFormats48Bit
6345                 {
6346                         VK_FORMAT_R16G16B16_UNORM,
6347                         VK_FORMAT_R16G16B16_SFLOAT
6348                 },
6349                 // From compatibleFormats64Bit
6350                 {
6351                         VK_FORMAT_R16G16B16A16_UNORM,
6352                         VK_FORMAT_R64_SFLOAT
6353                 },
6354                 // From compatibleFormats96Bit
6355                 {
6356                         VK_FORMAT_R32G32B32_UINT,
6357                         VK_FORMAT_R32G32B32_SFLOAT
6358                 },
6359                 // From compatibleFormats128Bit
6360                 {
6361                         VK_FORMAT_R32G32B32A32_UINT,
6362                         VK_FORMAT_R64G64_SFLOAT
6363                 },
6364                 // From compatibleFormats192Bit
6365                 {
6366                         VK_FORMAT_R64G64B64_UINT,
6367                         VK_FORMAT_R64G64B64_SFLOAT,
6368                 },
6369                 // From compatibleFormats256Bit
6370                 {
6371                         VK_FORMAT_R64G64B64A64_UINT,
6372                         VK_FORMAT_R64G64B64A64_SFLOAT
6373                 }
6374         };
6375
6376         const tcu::UVec2                imageDimensions[]       =
6377         {
6378                 // large pot x small pot
6379                 tcu::UVec2(4096,        4u),
6380                 tcu::UVec2(8192,        4u),
6381                 tcu::UVec2(16384,       4u),
6382                 tcu::UVec2(32768,       4u),
6383
6384                 // large pot x small npot
6385                 tcu::UVec2(4096,        6u),
6386                 tcu::UVec2(8192,        6u),
6387                 tcu::UVec2(16384,       6u),
6388                 tcu::UVec2(32768,       6u),
6389
6390                 // small pot x large pot
6391                 tcu::UVec2(4u, 4096),
6392                 tcu::UVec2(4u, 8192),
6393                 tcu::UVec2(4u, 16384),
6394                 tcu::UVec2(4u, 32768),
6395
6396                 // small npot x large pot
6397                 tcu::UVec2(6u, 4096),
6398                 tcu::UVec2(6u, 8192),
6399                 tcu::UVec2(6u, 16384),
6400                 tcu::UVec2(6u, 32768)
6401         };
6402
6403         const VkImageLayout             copySrcLayouts[]        =
6404         {
6405                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6406                 VK_IMAGE_LAYOUT_GENERAL
6407         };
6408
6409         const VkImageLayout             copyDstLayouts[]        =
6410         {
6411                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6412                 VK_IMAGE_LAYOUT_GENERAL
6413         };
6414
6415         if (allocationKind == ALLOCATION_KIND_DEDICATED)
6416         {
6417                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
6418                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
6419         }
6420
6421         // Image dimensions
6422         for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
6423         {
6424                 CopyRegion                              copyRegion;
6425                 CopyColorTestParams             testParams;
6426
6427                 const VkExtent3D                extent                  = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
6428
6429                 const VkImageCopy               testCopy                =
6430                 {
6431                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6432                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
6433                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6434                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
6435                         extent,                         // VkExtent3D                           extent;
6436                 };
6437
6438                 testParams.params.src.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
6439                 testParams.params.src.image.imageType   = VK_IMAGE_TYPE_2D;
6440                 testParams.params.src.image.extent              = extent;
6441
6442                 testParams.params.dst.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
6443                 testParams.params.dst.image.imageType   = VK_IMAGE_TYPE_2D;
6444                 testParams.params.dst.image.extent              = extent;
6445
6446                 copyRegion.imageCopy                                    = testCopy;
6447                 testParams.params.allocationKind                = allocationKind;
6448                 testParams.params.extensionUse                  = extensionUse;
6449
6450                 testParams.params.regions.push_back(copyRegion);
6451
6452                 const std::string       dimensionStr            = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
6453                                                                                                   + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
6454                 tcu::TestCaseGroup*     imageSizeGroup          = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
6455
6456                 // Compatible formats for copying
6457                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
6458                 {
6459                         const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
6460
6461                         testParams.compatibleFormats = compatibleFormats;
6462
6463                         // Source image format
6464                         for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
6465                         {
6466                                 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
6467
6468                                 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
6469                                         continue;
6470
6471                                 const std::string       srcDescription  = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
6472                                 tcu::TestCaseGroup*     srcFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
6473
6474                                 // Destination image format
6475                                 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
6476                                 {
6477                                         testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
6478
6479                                         if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
6480                                                 continue;
6481
6482                                         if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
6483                                                 continue;
6484
6485                                         if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
6486                                         {
6487                                                 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
6488                                                         || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
6489                                                         continue;
6490                                         }
6491
6492                                         const std::string       dstDescription  = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
6493                                         tcu::TestCaseGroup*     dstFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
6494
6495                                         // Source/destionation image layouts
6496                                         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
6497                                         {
6498                                                 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
6499
6500                                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
6501                                                 {
6502                                                         testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
6503
6504                                                         const std::string       testName        = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
6505                                                         const std::string       description     = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
6506                                                         const TestParams        params          = testParams.params;
6507
6508                                                         dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
6509                                                 }
6510                                         }
6511
6512                                         srcFormatGroup->addChild(dstFormatGroup);
6513                                 }
6514
6515                                 imageSizeGroup->addChild(srcFormatGroup);
6516                         }
6517                 }
6518
6519                 group->addChild(imageSizeGroup);
6520         }
6521 }
6522
6523 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
6524 {
6525         const VkImageLayout copySrcLayouts[]            =
6526         {
6527                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6528                 VK_IMAGE_LAYOUT_GENERAL
6529         };
6530         const VkImageLayout copyDstLayouts[]            =
6531         {
6532                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6533                 VK_IMAGE_LAYOUT_GENERAL
6534         };
6535
6536         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
6537         {
6538                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
6539                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
6540                 {
6541                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
6542
6543                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
6544                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
6545                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
6546                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
6547                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
6548                 }
6549         }
6550 }
6551
6552 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6553 {
6554         const VkFormat  depthAndStencilFormats[]        =
6555         {
6556                 VK_FORMAT_D16_UNORM,
6557                 VK_FORMAT_X8_D24_UNORM_PACK32,
6558                 VK_FORMAT_D32_SFLOAT,
6559                 VK_FORMAT_S8_UINT,
6560                 VK_FORMAT_D16_UNORM_S8_UINT,
6561                 VK_FORMAT_D24_UNORM_S8_UINT,
6562                 VK_FORMAT_D32_SFLOAT_S8_UINT,
6563         };
6564
6565         // 2D tests.
6566         {
6567                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
6568
6569                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
6570                 {
6571                         TestParams      params;
6572                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6573                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6574                         params.src.image.extent                         = defaultExtent;
6575                         params.dst.image.extent                         = defaultExtent;
6576                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
6577                         params.dst.image.format                         = params.src.image.format;
6578                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6579                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6580                         params.allocationKind                           = allocationKind;
6581                         params.extensionUse                                     = extensionUse;
6582                         params.separateDepthStencilLayouts      = DE_FALSE;
6583
6584                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
6585                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
6586
6587                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
6588                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6589                         const VkImageSubresourceLayers          defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6590
6591                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
6592                         {
6593                                 CopyRegion                      copyRegion;
6594                                 const VkOffset3D        srcOffset       = {0, 0, 0};
6595                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
6596                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
6597
6598                                 if (hasDepth)
6599                                 {
6600                                         const VkImageCopy                               testCopy        =
6601                                         {
6602                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
6603                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6604                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
6605                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6606                                                 extent,                                         // VkExtent3D                           extent;
6607                                         };
6608
6609                                         copyRegion.imageCopy    = testCopy;
6610                                         params.regions.push_back(copyRegion);
6611                                 }
6612                                 if (hasStencil)
6613                                 {
6614                                         const VkImageCopy                               testCopy        =
6615                                         {
6616                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
6617                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6618                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
6619                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6620                                                 extent,                                         // VkExtent3D                           extent;
6621                                         };
6622
6623                                         copyRegion.imageCopy    = testCopy;
6624                                         params.regions.push_back(copyRegion);
6625                                 }
6626                         }
6627
6628                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
6629                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
6630                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6631
6632                         if (hasDepth && hasStencil)
6633                         {
6634                                 params.separateDepthStencilLayouts      = DE_TRUE;
6635                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
6636                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
6637                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6638
6639                                 // DS Image copy
6640                                 {
6641                                         params.separateDepthStencilLayouts      = DE_FALSE;
6642                                         // Clear previous vkImageCopy elements
6643                                         params.regions.clear();
6644
6645                                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
6646                                         {
6647                                                 CopyRegion                      copyRegion;
6648                                                 const VkOffset3D        srcOffset       = {0, 0, 0};
6649                                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
6650                                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
6651
6652                                                 const VkImageCopy                               testCopy        =
6653                                                 {
6654                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     srcSubresource;
6655                                                         srcOffset,                                      // VkOffset3D                           srcOffset;
6656                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     dstSubresource;
6657                                                         dstOffset,                                      // VkOffset3D                           dstOffset;
6658                                                         extent,                                         // VkExtent3D                           extent;
6659                                                 };
6660
6661                                                 copyRegion.imageCopy    = testCopy;
6662                                                 params.regions.push_back(copyRegion);
6663                                         }
6664
6665                                         const std::string testName3             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
6666                                         const std::string description3  = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
6667                                         addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6668                                 }
6669                         }
6670                 }
6671
6672                 group->addChild(subGroup.release());
6673         }
6674
6675         // 1D tests.
6676         {
6677                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
6678
6679                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
6680                 {
6681                         TestParams      params;
6682                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
6683                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
6684                         params.src.image.extent                         = default1dExtent;
6685                         params.dst.image.extent                         = default1dExtent;
6686                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
6687                         params.dst.image.format                         = params.src.image.format;
6688                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6689                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6690                         params.allocationKind                           = allocationKind;
6691                         params.extensionUse                                     = extensionUse;
6692
6693                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
6694                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
6695
6696                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
6697                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6698
6699                         for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
6700                         {
6701                                 CopyRegion                      copyRegion;
6702                                 const VkOffset3D        srcOffset       = {0, 0, 0};
6703                                 const VkOffset3D        dstOffset       = {i, 0, 0};
6704                                 const VkExtent3D        extent          = {defaultFourthSize, 1, 1};
6705
6706                                 if (hasDepth)
6707                                 {
6708                                         const VkImageCopy                               testCopy        =
6709                                         {
6710                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
6711                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6712                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
6713                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6714                                                 extent,                                         // VkExtent3D                           extent;
6715                                         };
6716
6717                                         copyRegion.imageCopy    = testCopy;
6718                                         params.regions.push_back(copyRegion);
6719                                 }
6720                                 if (hasStencil)
6721                                 {
6722                                         const VkImageCopy                               testCopy        =
6723                                         {
6724                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
6725                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6726                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
6727                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6728                                                 extent,                                         // VkExtent3D                           extent;
6729                                         };
6730
6731                                         copyRegion.imageCopy    = testCopy;
6732                                         params.regions.push_back(copyRegion);
6733                                 }
6734                         }
6735
6736                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
6737                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
6738                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6739
6740                         if (hasDepth && hasStencil)
6741                         {
6742                                 params.separateDepthStencilLayouts      = DE_TRUE;
6743                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
6744                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
6745                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6746                         }
6747                 }
6748
6749                 group->addChild(subGroup.release());
6750         }
6751
6752         // 3D tests. Note we use smaller dimensions here for performance reasons.
6753         {
6754                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
6755
6756                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
6757                 {
6758                         TestParams      params;
6759                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
6760                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
6761                         params.src.image.extent                         = default3dExtent;
6762                         params.dst.image.extent                         = default3dExtent;
6763                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
6764                         params.dst.image.format                         = params.src.image.format;
6765                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6766                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6767                         params.allocationKind                           = allocationKind;
6768                         params.extensionUse                                     = extensionUse;
6769
6770                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
6771                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
6772
6773                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
6774                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6775
6776                         for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
6777                         {
6778                                 CopyRegion                      copyRegion;
6779                                 const VkOffset3D        srcOffset       = {0, 0, 0};
6780                                 const VkOffset3D        dstOffset       = {i, defaultFourthSize - i - defaultSixteenthSize, i};
6781                                 const VkExtent3D        extent          = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
6782
6783                                 if (hasDepth)
6784                                 {
6785                                         const VkImageCopy                               testCopy        =
6786                                         {
6787                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
6788                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6789                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
6790                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6791                                                 extent,                                         // VkExtent3D                           extent;
6792                                         };
6793
6794                                         copyRegion.imageCopy    = testCopy;
6795                                         params.regions.push_back(copyRegion);
6796                                 }
6797                                 if (hasStencil)
6798                                 {
6799                                         const VkImageCopy                               testCopy        =
6800                                         {
6801                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
6802                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
6803                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
6804                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
6805                                                 extent,                                         // VkExtent3D                           extent;
6806                                         };
6807
6808                                         copyRegion.imageCopy    = testCopy;
6809                                         params.regions.push_back(copyRegion);
6810                                 }
6811                         }
6812
6813                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
6814                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
6815                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6816
6817                         if (hasDepth && hasStencil)
6818                         {
6819                                 params.separateDepthStencilLayouts      = DE_TRUE;
6820                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
6821                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
6822                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
6823                         }
6824                 }
6825
6826                 group->addChild(subGroup.release());
6827         }
6828 }
6829
6830 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6831 {
6832         addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
6833         addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
6834 }
6835
6836 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6837 {
6838         tcu::TestContext& testCtx       = group->getTestContext();
6839
6840         {
6841                 TestParams      params3DTo2D;
6842                 const deUint32  slicesLayers                    = 16u;
6843                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
6844                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6845                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
6846                 params3DTo2D.src.image.extent.depth             = slicesLayers;
6847                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6848                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6849                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
6850                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6851                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
6852                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
6853                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6854                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6855                 params3DTo2D.allocationKind                             = allocationKind;
6856                 params3DTo2D.extensionUse                               = extensionUse;
6857
6858                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
6859                 {
6860                         const VkImageSubresourceLayers  sourceLayer     =
6861                         {
6862                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6863                                 0u,                                                     // deUint32                             mipLevel;
6864                                 0u,                                                     // deUint32                             baseArrayLayer;
6865                                 1u                                                      // deUint32                             layerCount;
6866                         };
6867
6868                         const VkImageSubresourceLayers  destinationLayer        =
6869                         {
6870                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6871                                 0u,                                                     // deUint32                             mipLevel;
6872                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
6873                                 1u                                                      // deUint32                             layerCount;
6874                         };
6875
6876                         const VkImageCopy                               testCopy        =
6877                         {
6878                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
6879                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           srcOffset;
6880                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
6881                                 {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
6882                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
6883                         };
6884
6885                         CopyRegion      imageCopy;
6886                         imageCopy.imageCopy     = testCopy;
6887
6888                         params3DTo2D.regions.push_back(imageCopy);
6889                 }
6890                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
6891         }
6892
6893         {
6894                 TestParams      params2DTo3D;
6895                 const deUint32  slicesLayers                    = 16u;
6896                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
6897                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6898                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
6899                 params2DTo3D.src.image.extent.depth             = slicesLayers;
6900                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6901                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6902                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
6903                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6904                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
6905                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
6906                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6907                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6908                 params2DTo3D.allocationKind                             = allocationKind;
6909                 params2DTo3D.extensionUse                               = extensionUse;
6910
6911                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
6912                 {
6913                         const VkImageSubresourceLayers  sourceLayer     =
6914                         {
6915                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6916                                 0u,                                                     // deUint32                             mipLevel;
6917                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
6918                                 1u                                                      // deUint32                             layerCount;
6919                         };
6920
6921                         const VkImageSubresourceLayers  destinationLayer        =
6922                         {
6923                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6924                                 0u,                                                     // deUint32                             mipLevel;
6925                                 0u,                                                     // deUint32                             baseArrayLayer;
6926                                 1u                                                      // deUint32                             layerCount;
6927                         };
6928
6929                         const VkImageCopy                               testCopy        =
6930                         {
6931                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
6932                                 {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
6933                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
6934                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           dstOffset;
6935                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
6936                         };
6937
6938                         CopyRegion      imageCopy;
6939                         imageCopy.imageCopy     = testCopy;
6940
6941                         params2DTo3D.regions.push_back(imageCopy);
6942                 }
6943
6944                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
6945         }
6946
6947         {
6948                 TestParams      params3DTo2D;
6949                 const deUint32  slicesLayers                    = 16u;
6950                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
6951                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6952                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
6953                 params3DTo2D.src.image.extent.depth             = slicesLayers;
6954                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6955                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6956                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
6957                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
6958                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
6959                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
6960                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
6961                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6962                 params3DTo2D.allocationKind                             = allocationKind;
6963                 params3DTo2D.extensionUse                               = extensionUse;
6964
6965                 {
6966                         const VkImageSubresourceLayers  sourceLayer     =
6967                         {
6968                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6969                                 0u,                                                     // deUint32                             mipLevel;
6970                                 0u,                                                     // deUint32                             baseArrayLayer;
6971                                 1u                                                      // deUint32                             layerCount;
6972                         };
6973
6974                         const VkImageSubresourceLayers  destinationLayer        =
6975                         {
6976                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6977                                 0u,                                                     // deUint32                             mipLevel;
6978                                 0,                                                      // deUint32                             baseArrayLayer;
6979                                 slicesLayers                            // deUint32                             layerCount;
6980                         };
6981
6982                         const VkImageCopy                               testCopy        =
6983                         {
6984                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
6985                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
6986                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
6987                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
6988                                 params3DTo2D.src.image.extent   // VkExtent3D                           extent;
6989                         };
6990
6991                         CopyRegion      imageCopy;
6992                         imageCopy.imageCopy     = testCopy;
6993
6994                         params3DTo2D.regions.push_back(imageCopy);
6995                 }
6996                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
6997         }
6998
6999         {
7000                 TestParams      params2DTo3D;
7001                 const deUint32  slicesLayers                    = 16u;
7002                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
7003                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7004                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
7005                 params2DTo3D.src.image.extent.depth             = slicesLayers;
7006                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7007                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7008                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
7009                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7010                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
7011                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
7012                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7013                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7014                 params2DTo3D.allocationKind                             = allocationKind;
7015                 params2DTo3D.extensionUse                               = extensionUse;
7016
7017                 {
7018                         const VkImageSubresourceLayers  sourceLayer     =
7019                         {
7020                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7021                                 0u,                                                     // deUint32                             mipLevel;
7022                                 0u,                                                     // deUint32                             baseArrayLayer;
7023                                 slicesLayers                            // deUint32                             layerCount;
7024                         };
7025
7026                         const VkImageSubresourceLayers  destinationLayer        =
7027                         {
7028                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7029                                 0u,                                                     // deUint32                             mipLevel;
7030                                 0u,                                                     // deUint32                             baseArrayLayer;
7031                                 1u                                                      // deUint32                             layerCount;
7032                         };
7033
7034                         const VkImageCopy                               testCopy        =
7035                         {
7036                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
7037                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
7038                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
7039                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
7040                                 params2DTo3D.src.image.extent,  // VkExtent3D                           extent;
7041                         };
7042
7043                         CopyRegion      imageCopy;
7044                         imageCopy.imageCopy     = testCopy;
7045
7046                         params2DTo3D.regions.push_back(imageCopy);
7047                 }
7048
7049                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
7050         }
7051
7052         {
7053                 TestParams      params3DTo2D;
7054                 const deUint32  slicesLayers                    = 16u;
7055                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
7056                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7057                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
7058                 params3DTo2D.src.image.extent.depth             = slicesLayers;
7059                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7060                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7061                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
7062                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7063                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
7064                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
7065                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7066                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7067                 params3DTo2D.allocationKind                             = allocationKind;
7068                 params3DTo2D.extensionUse                               = extensionUse;
7069
7070                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
7071                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
7072
7073                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
7074                 {
7075                         const VkImageSubresourceLayers  sourceLayer     =
7076                         {
7077                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7078                                 0u,                                                     // deUint32                             mipLevel;
7079                                 0u,                                                     // deUint32                             baseArrayLayer;
7080                                 1u                                                      // deUint32                             layerCount;
7081                         };
7082
7083                         const VkImageSubresourceLayers  destinationLayer        =
7084                         {
7085                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
7086                                         0u,                                                             // deUint32                             mipLevel;
7087                                         slicesLayersNdx,                                // deUint32                             baseArrayLayer;
7088                                         1u                                                              // deUint32                             layerCount;
7089                         };
7090
7091
7092                         const VkImageCopy                               testCopy        =
7093                         {
7094                                 sourceLayer,                                                                                                                    // VkImageSubresourceLayers     srcSubresource;
7095                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D                           srcOffset;
7096                                         destinationLayer,                                                                                                       // VkImageSubresourceLayers     dstSubresource;
7097                                         {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                         // VkOffset3D                           dstOffset;
7098                                         {
7099                                                 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
7100                                                 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
7101                                                 1
7102                                         }                                                                                                                                       // VkExtent3D                           extent;
7103                         };
7104
7105                         CopyRegion      imageCopy;
7106                         imageCopy.imageCopy = testCopy;
7107                         params3DTo2D.regions.push_back(imageCopy);
7108                 }
7109                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
7110         }
7111
7112         {
7113                 TestParams      params2DTo3D;
7114                 const deUint32  slicesLayers                    = 16u;
7115                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
7116                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7117                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
7118                 params2DTo3D.src.image.extent.depth             = slicesLayers;
7119                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7120                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7121                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
7122                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7123                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
7124                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
7125                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7126                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7127                 params2DTo3D.allocationKind                             = allocationKind;
7128                 params2DTo3D.extensionUse                               = extensionUse;
7129
7130                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
7131                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
7132
7133                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
7134                 {
7135                         const VkImageSubresourceLayers  sourceLayer     =
7136                         {
7137                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7138                                 0u,                                                     // deUint32                             mipLevel;
7139                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
7140                                 1u                                                      // deUint32                             layerCount;
7141                         };
7142
7143                         const VkImageSubresourceLayers  destinationLayer        =
7144                         {
7145                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7146                                 0u,                                                     // deUint32                             mipLevel;
7147                                 0u,                                                     // deUint32                             baseArrayLayer;
7148                                 1u                                                      // deUint32                             layerCount;
7149                         };
7150
7151                         const VkImageCopy                               testCopy        =
7152                         {
7153                                 sourceLayer,                                                                                                                            // VkImageSubresourceLayers     srcSubresource;
7154                                 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                                         // VkOffset3D                           srcOffset;
7155                                 destinationLayer,                                                                                                                       // VkImageSubresourceLayers     dstSubresource;
7156                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},       // VkOffset3D                           dstOffset;
7157                                 {
7158                                         defaultHalfExtent.width - regionWidth*slicesLayersNdx,
7159                                         defaultHalfExtent.height - regionHeight*slicesLayersNdx,
7160                                         1
7161                                 }                                                                                                                                                       // VkExtent3D                           extent;
7162                         };
7163
7164                         CopyRegion      imageCopy;
7165                         imageCopy.imageCopy     = testCopy;
7166
7167                         params2DTo3D.regions.push_back(imageCopy);
7168                 }
7169
7170                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
7171         }
7172 }
7173
7174 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7175 {
7176         tcu::TestContext& testCtx       = group->getTestContext();
7177
7178         {
7179                 TestParams      paramsCubeToArray;
7180                 const deUint32  arrayLayers                                     = 6u;
7181                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7182                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
7183                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7184                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
7185                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
7186                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7187                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7188                 paramsCubeToArray.dst.image.createFlags         = 0;
7189                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
7190                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7191                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
7192                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
7193                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7194                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7195                 paramsCubeToArray.allocationKind                        = allocationKind;
7196                 paramsCubeToArray.extensionUse                          = extensionUse;
7197
7198                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
7199                 {
7200                         const VkImageSubresourceLayers  sourceLayer     =
7201                                 {
7202                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7203                                         0u,                                                     // deUint32                             mipLevel;
7204                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7205                                         1u                                                      // deUint32                             layerCount;
7206                                 };
7207
7208                         const VkImageSubresourceLayers  destinationLayer        =
7209                                 {
7210                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7211                                         0u,                                                     // deUint32                             mipLevel;
7212                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7213                                         1u                                                      // deUint32                             layerCount;
7214                                 };
7215
7216                         const VkImageCopy                               testCopy        =
7217                                 {
7218                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7219                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7220                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7221                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7222                                         defaultHalfExtent                               // VkExtent3D                           extent;
7223                                 };
7224
7225                         CopyRegion      imageCopy;
7226                         imageCopy.imageCopy     = testCopy;
7227
7228                         paramsCubeToArray.regions.push_back(imageCopy);
7229                 }
7230
7231                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
7232         }
7233
7234         {
7235                 TestParams      paramsCubeToArray;
7236                 const deUint32  arrayLayers                                     = 6u;
7237                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7238                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
7239                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7240                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
7241                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
7242                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7243                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7244                 paramsCubeToArray.dst.image.createFlags         = 0;
7245                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
7246                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7247                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
7248                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
7249                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7250                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7251                 paramsCubeToArray.allocationKind                        = allocationKind;
7252                 paramsCubeToArray.extensionUse                          = extensionUse;
7253
7254                 {
7255                         const VkImageSubresourceLayers  sourceLayer     =
7256                                 {
7257                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7258                                         0u,                                                     // deUint32                             mipLevel;
7259                                         0u,                                                     // deUint32                             baseArrayLayer;
7260                                         arrayLayers                                     // deUint32                             layerCount;
7261                                 };
7262
7263                         const VkImageSubresourceLayers  destinationLayer        =
7264                                 {
7265                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7266                                         0u,                                                     // deUint32                             mipLevel;
7267                                         0u,                                                     // deUint32                             baseArrayLayer;
7268                                         arrayLayers                                     // deUint32                             layerCount;
7269                                 };
7270
7271                         const VkImageCopy                               testCopy        =
7272                                 {
7273                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7274                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7275                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7276                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7277                                         defaultHalfExtent                       // VkExtent3D                           extent;
7278                                 };
7279
7280                         CopyRegion      imageCopy;
7281                         imageCopy.imageCopy     = testCopy;
7282
7283                         paramsCubeToArray.regions.push_back(imageCopy);
7284                 }
7285
7286                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
7287         }
7288
7289         {
7290                 TestParams      paramsArrayToCube;
7291                 const deUint32  arrayLayers                                     = 6u;
7292                 paramsArrayToCube.src.image.createFlags         = 0;
7293                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
7294                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7295                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
7296                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
7297                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7298                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7299                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7300                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
7301                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7302                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
7303                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
7304                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7305                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7306                 paramsArrayToCube.allocationKind                        = allocationKind;
7307                 paramsArrayToCube.extensionUse                          = extensionUse;
7308
7309                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
7310                 {
7311                         const VkImageSubresourceLayers  sourceLayer     =
7312                                 {
7313                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7314                                         0u,                                                     // deUint32                             mipLevel;
7315                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7316                                         1u                                                      // deUint32                             layerCount;
7317                                 };
7318
7319                         const VkImageSubresourceLayers  destinationLayer =
7320                                 {
7321                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7322                                         0u,                                                     // deUint32                             mipLevel;
7323                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7324                                         1u                                                      // deUint32                             layerCount;
7325                                 };
7326
7327                         const VkImageCopy                               testCopy =
7328                                 {
7329                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7330                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7331                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7332                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7333                                         defaultHalfExtent                       // VkExtent3D                           extent;
7334                                 };
7335
7336                         CopyRegion      imageCopy;
7337                         imageCopy.imageCopy     = testCopy;
7338
7339                         paramsArrayToCube.regions.push_back(imageCopy);
7340                 }
7341
7342                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
7343         }
7344
7345         {
7346                 TestParams      paramsArrayToCube;
7347                 const deUint32  arrayLayers                                     = 6u;
7348                 paramsArrayToCube.src.image.createFlags         = 0;
7349                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
7350                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7351                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
7352                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
7353                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7354                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7355                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7356                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
7357                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7358                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
7359                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
7360                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7361                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7362                 paramsArrayToCube.allocationKind                        = allocationKind;
7363                 paramsArrayToCube.extensionUse                          = extensionUse;
7364
7365                 {
7366                         const VkImageSubresourceLayers sourceLayer =
7367                                 {
7368                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
7369                                         0u,                                                             // deUint32                             mipLevel;
7370                                         0u,                                                             // deUint32                             baseArrayLayer;
7371                                         arrayLayers                                             // deUint32                             layerCount;
7372                                 };
7373
7374                         const VkImageSubresourceLayers destinationLayer =
7375                                 {
7376                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
7377                                         0u,                                                             // deUint32                             mipLevel;
7378                                         0u,                                                             // deUint32                             baseArrayLayer;
7379                                         arrayLayers                                             // deUint32                             layerCount;
7380                                 };
7381
7382                         const VkImageCopy                               testCopy =
7383                                 {
7384                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
7385                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
7386                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
7387                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
7388                                         defaultHalfExtent                               // VkExtent3D                           extent;
7389                                 };
7390
7391                         CopyRegion imageCopy;
7392                         imageCopy.imageCopy = testCopy;
7393
7394                         paramsArrayToCube.regions.push_back(imageCopy);
7395                 }
7396
7397                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
7398         }
7399
7400         {
7401                 TestParams      paramsCubeToArray;
7402                 const deUint32  arrayLayers                                     = 6u;
7403                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7404                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
7405                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7406                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
7407                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
7408                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7409                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7410                 paramsCubeToArray.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7411                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
7412                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
7413                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
7414                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
7415                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
7416                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7417                 paramsCubeToArray.allocationKind                        = allocationKind;
7418                 paramsCubeToArray.extensionUse                          = extensionUse;
7419
7420                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
7421                 {
7422                         const VkImageSubresourceLayers  sourceLayer     =
7423                                 {
7424                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7425                                         0u,                                                     // deUint32                             mipLevel;
7426                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7427                                         1u                                                      // deUint32                             layerCount;
7428                                 };
7429
7430                         const VkImageSubresourceLayers  destinationLayer        =
7431                                 {
7432                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7433                                         0u,                                                     // deUint32                             mipLevel;
7434                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7435                                         1u                                                      // deUint32                             layerCount;
7436                                 };
7437
7438                         const VkImageCopy                               testCopy        =
7439                                 {
7440                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7441                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7442                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7443                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7444                                         defaultHalfExtent                               // VkExtent3D                           extent;
7445                                 };
7446
7447                         CopyRegion      imageCopy;
7448                         imageCopy.imageCopy     = testCopy;
7449
7450                         paramsCubeToArray.regions.push_back(imageCopy);
7451                 }
7452
7453                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
7454         }
7455
7456         {
7457                 TestParams      paramsCubeToCube;
7458                 const deUint32  arrayLayers                                     = 6u;
7459                 paramsCubeToCube.src.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7460                 paramsCubeToCube.src.image.imageType            = VK_IMAGE_TYPE_2D;
7461                 paramsCubeToCube.src.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
7462                 paramsCubeToCube.src.image.extent                       = defaultHalfExtent;
7463                 paramsCubeToCube.src.image.extent.depth         = arrayLayers;
7464                 paramsCubeToCube.src.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
7465                 paramsCubeToCube.src.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7466                 paramsCubeToCube.dst.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
7467                 paramsCubeToCube.dst.image.imageType            = VK_IMAGE_TYPE_2D;
7468                 paramsCubeToCube.dst.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
7469                 paramsCubeToCube.dst.image.extent                       = defaultHalfExtent;
7470                 paramsCubeToCube.dst.image.extent.depth         = arrayLayers;
7471                 paramsCubeToCube.dst.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
7472                 paramsCubeToCube.dst.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7473                 paramsCubeToCube.allocationKind                         = allocationKind;
7474                 paramsCubeToCube.extensionUse                           = extensionUse;
7475
7476                 {
7477                         const VkImageSubresourceLayers  sourceLayer     =
7478                                 {
7479                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7480                                         0u,                                                     // deUint32                             mipLevel;
7481                                         0u,                                                     // deUint32                             baseArrayLayer;
7482                                         arrayLayers                                     // deUint32                             layerCount;
7483                                 };
7484
7485                         const VkImageSubresourceLayers  destinationLayer        =
7486                                 {
7487                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7488                                         0u,                                                     // deUint32                             mipLevel;
7489                                         0u,                                                     // deUint32                             baseArrayLayer;
7490                                         arrayLayers                                     // deUint32                             layerCount;
7491                                 };
7492
7493                         const VkImageCopy                               testCopy        =
7494                                 {
7495                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7496                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7497                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7498                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7499                                         defaultHalfExtent                       // VkExtent3D                           extent;
7500                                 };
7501
7502                         CopyRegion      imageCopy;
7503                         imageCopy.imageCopy     = testCopy;
7504
7505                         paramsCubeToCube.regions.push_back(imageCopy);
7506                 }
7507
7508                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
7509         }
7510 }
7511
7512 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7513 {
7514         tcu::TestContext& testCtx       = group->getTestContext();
7515
7516         {
7517                 TestParams      paramsArrayToArray;
7518                 const deUint32  arrayLayers                                     = 16u;
7519                 paramsArrayToArray.src.image.imageType          = VK_IMAGE_TYPE_2D;
7520                 paramsArrayToArray.src.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
7521                 paramsArrayToArray.src.image.extent                     = defaultHalfExtent;
7522                 paramsArrayToArray.src.image.extent.depth       = arrayLayers;
7523                 paramsArrayToArray.src.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
7524                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7525                 paramsArrayToArray.dst.image.imageType          = VK_IMAGE_TYPE_2D;
7526                 paramsArrayToArray.dst.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
7527                 paramsArrayToArray.dst.image.extent                     = defaultHalfExtent;
7528                 paramsArrayToArray.dst.image.extent.depth       = arrayLayers;
7529                 paramsArrayToArray.dst.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
7530                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7531                 paramsArrayToArray.allocationKind                       = allocationKind;
7532                 paramsArrayToArray.extensionUse                         = extensionUse;
7533
7534                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
7535                 {
7536                         const VkImageSubresourceLayers  sourceLayer     =
7537                                         {
7538                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7539                                                         0u,                                                     // deUint32                             mipLevel;
7540                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7541                                                         1u                                                      // deUint32                             layerCount;
7542                                         };
7543
7544                         const VkImageSubresourceLayers  destinationLayer =
7545                                         {
7546                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7547                                                         0u,                                                     // deUint32                             mipLevel;
7548                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
7549                                                         1u                                                      // deUint32                             layerCount;
7550                                         };
7551
7552                         const VkImageCopy                               testCopy =
7553                                         {
7554                                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
7555                                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7556                                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
7557                                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
7558                                                         defaultHalfExtent                       // VkExtent3D                           extent;
7559                                         };
7560
7561                         CopyRegion      imageCopy;
7562                         imageCopy.imageCopy     = testCopy;
7563
7564                         paramsArrayToArray.regions.push_back(imageCopy);
7565                 }
7566
7567                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
7568         }
7569
7570         {
7571                 TestParams      paramsArrayToArray;
7572                 const deUint32  arrayLayers                                             = 16u;
7573                 paramsArrayToArray.src.image.imageType                  = VK_IMAGE_TYPE_2D;
7574                 paramsArrayToArray.src.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
7575                 paramsArrayToArray.src.image.extent                             = defaultHalfExtent;
7576                 paramsArrayToArray.src.image.extent.depth               = arrayLayers;
7577                 paramsArrayToArray.src.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
7578                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7579                 paramsArrayToArray.dst.image.imageType                  = VK_IMAGE_TYPE_2D;
7580                 paramsArrayToArray.dst.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
7581                 paramsArrayToArray.dst.image.extent                             = defaultHalfExtent;
7582                 paramsArrayToArray.dst.image.extent.depth               = arrayLayers;
7583                 paramsArrayToArray.dst.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
7584                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7585                 paramsArrayToArray.allocationKind                               = allocationKind;
7586                 paramsArrayToArray.extensionUse                                 = extensionUse;
7587
7588                 {
7589                         const VkImageSubresourceLayers sourceLayer =
7590                                         {
7591                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
7592                                                         0u,                                                             // deUint32                             mipLevel;
7593                                                         0u,                                                             // deUint32                             baseArrayLayer;
7594                                                         arrayLayers                                             // deUint32                             layerCount;
7595                                         };
7596
7597                         const VkImageSubresourceLayers destinationLayer =
7598                                         {
7599                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
7600                                                         0u,                                                             // deUint32                             mipLevel;
7601                                                         0u,                                                             // deUint32                             baseArrayLayer;
7602                                                         arrayLayers                                             // deUint32                             layerCount;
7603                                         };
7604
7605                         const VkImageCopy                               testCopy =
7606                                         {
7607                                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
7608                                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
7609                                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
7610                                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
7611                                                         defaultHalfExtent                               // VkExtent3D                           extent;
7612                                         };
7613
7614                         CopyRegion imageCopy;
7615                         imageCopy.imageCopy = testCopy;
7616
7617                         paramsArrayToArray.regions.push_back(imageCopy);
7618                 }
7619
7620                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
7621         }
7622 };
7623
7624 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7625 {
7626         addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
7627         addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
7628         addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
7629         addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
7630         addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
7631         addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
7632 }
7633
7634 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7635 {
7636         tcu::TestContext& testCtx       = group->getTestContext();
7637
7638         {
7639                 TestParams      params;
7640                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7641                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7642                 params.src.image.extent                         = defaultExtent;
7643                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7644                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7645                 params.dst.buffer.size                          = defaultSize * defaultSize;
7646                 params.allocationKind                           = allocationKind;
7647                 params.extensionUse                                     = extensionUse;
7648
7649                 const VkBufferImageCopy bufferImageCopy =
7650                 {
7651                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
7652                         0u,                                                                                     // deUint32                                     bufferRowLength;
7653                         0u,                                                                                     // deUint32                                     bufferImageHeight;
7654                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7655                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
7656                         defaultExtent                                                           // VkExtent3D                           imageExtent;
7657                 };
7658                 CopyRegion      copyRegion;
7659                 copyRegion.bufferImageCopy      = bufferImageCopy;
7660
7661                 params.regions.push_back(copyRegion);
7662
7663                 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
7664         }
7665
7666         {
7667                 TestParams      params;
7668                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7669                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7670                 params.src.image.extent                         = defaultExtent;
7671                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7672                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7673                 params.dst.buffer.size                          = defaultSize * defaultSize;
7674                 params.allocationKind                           = allocationKind;
7675                 params.extensionUse                                     = extensionUse;
7676
7677                 const VkBufferImageCopy bufferImageCopy =
7678                 {
7679                         defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
7680                         0u,                                                                                     // deUint32                                     bufferRowLength;
7681                         0u,                                                                                     // deUint32                                     bufferImageHeight;
7682                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7683                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7684                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7685                 };
7686                 CopyRegion      copyRegion;
7687                 copyRegion.bufferImageCopy      = bufferImageCopy;
7688
7689                 params.regions.push_back(copyRegion);
7690
7691                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
7692         }
7693
7694         {
7695                 TestParams      params;
7696                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7697                 params.src.image.format                         = VK_FORMAT_R8_UNORM;
7698                 params.src.image.extent                         = defaultExtent;
7699                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7700                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7701                 params.dst.buffer.size                          = defaultSize * defaultSize;
7702                 params.allocationKind                           = allocationKind;
7703                 params.extensionUse                                     = extensionUse;
7704
7705                 const VkBufferImageCopy bufferImageCopy =
7706                 {
7707                         defaultSize * defaultHalfSize + 1u,             // VkDeviceSize                         bufferOffset;
7708                         0u,                                                                                     // deUint32                                     bufferRowLength;
7709                         0u,                                                                                     // deUint32                                     bufferImageHeight;
7710                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7711                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7712                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7713                 };
7714                 CopyRegion      copyRegion;
7715                 copyRegion.bufferImageCopy      = bufferImageCopy;
7716
7717                 params.regions.push_back(copyRegion);
7718
7719                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
7720         }
7721
7722         {
7723                 TestParams      params;
7724                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7725                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7726                 params.src.image.extent                         = defaultExtent;
7727                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7728                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7729                 params.dst.buffer.size                          = defaultSize * defaultSize;
7730                 params.allocationKind                           = allocationKind;
7731                 params.extensionUse                                     = extensionUse;
7732
7733                 const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
7734                 const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
7735                 const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
7736                 deUint32                        divisor         = 1;
7737                 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
7738                 {
7739                         const deUint32                  bufferRowLength         = defaultFourthSize;
7740                         const deUint32                  bufferImageHeight       = defaultFourthSize;
7741                         const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
7742                         DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
7743                         DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
7744                         DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
7745
7746                         CopyRegion                              region;
7747                         const VkBufferImageCopy bufferImageCopy         =
7748                         {
7749                                 offset,                                         // VkDeviceSize                         bufferOffset;
7750                                 bufferRowLength,                        // deUint32                                     bufferRowLength;
7751                                 bufferImageHeight,                      // deUint32                                     bufferImageHeight;
7752                                 defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
7753                                 {0, 0, 0},                                      // VkOffset3D                           imageOffset;
7754                                 imageExtent                                     // VkExtent3D                           imageExtent;
7755                         };
7756                         region.bufferImageCopy  = bufferImageCopy;
7757                         params.regions.push_back(region);
7758                 }
7759
7760                 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
7761         }
7762
7763         {
7764                 TestParams                              params;
7765                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7766                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7767                 params.src.image.extent                         = defaultExtent;
7768                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7769                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7770                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
7771                 params.allocationKind                           = allocationKind;
7772                 params.extensionUse                                     = extensionUse;
7773
7774                 const VkBufferImageCopy bufferImageCopy =
7775                 {
7776                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
7777                         defaultSize,                                                            // deUint32                                     bufferRowLength;
7778                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
7779                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7780                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7781                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7782                 };
7783                 CopyRegion                              copyRegion;
7784                 copyRegion.bufferImageCopy      = bufferImageCopy;
7785
7786                 params.regions.push_back(copyRegion);
7787
7788                 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
7789         }
7790
7791         {
7792                 TestParams                              params;
7793                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7794                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7795                 params.src.image.extent                         = defaultExtent;
7796                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7797                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7798                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
7799                 params.allocationKind                           = allocationKind;
7800                 params.extensionUse                                     = extensionUse;
7801
7802                 const VkBufferImageCopy bufferImageCopy =
7803                 {
7804                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
7805                         defaultSize,                                                            // deUint32                                     bufferRowLength;
7806                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
7807                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7808                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7809                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7810                 };
7811                 CopyRegion                              copyRegion;
7812                 copyRegion.bufferImageCopy      = bufferImageCopy;
7813
7814                 params.regions.push_back(copyRegion);
7815
7816                 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));
7817         }
7818
7819         {
7820                 TestParams                              params;
7821                 deUint32                                arrayLayers = 16u;
7822                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7823                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7824                 params.src.image.extent                         = defaultHalfExtent;
7825                 params.src.image.extent.depth           = arrayLayers;
7826                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7827                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7828                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
7829                 params.allocationKind                           = allocationKind;
7830                 params.extensionUse                                     = extensionUse;
7831
7832                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
7833                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
7834                 {
7835                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
7836                         const VkBufferImageCopy bufferImageCopy =
7837                                 {
7838                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
7839                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
7840                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
7841                                         {
7842                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
7843                                                 0u,                                                                                             // deUint32                             mipLevel;
7844                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
7845                                                 1u,                                                                                             // deUint32                             layerCount;
7846                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
7847                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
7848                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
7849                                 };
7850                         CopyRegion copyRegion;
7851                         copyRegion.bufferImageCopy = bufferImageCopy;
7852
7853                         params.regions.push_back(copyRegion);
7854                 }
7855                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
7856         }
7857
7858         {
7859                 TestParams                              params;
7860                 deUint32                                arrayLayers = 16u;
7861                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7862                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
7863                 params.src.image.extent                         = defaultHalfExtent;
7864                 params.src.image.extent.depth           = arrayLayers;
7865                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7866                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7867                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
7868                 params.allocationKind                           = allocationKind;
7869                 params.extensionUse                                     = extensionUse;
7870
7871                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
7872                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
7873                 {
7874                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
7875                         const VkBufferImageCopy bufferImageCopy =
7876                                 {
7877                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
7878                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
7879                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
7880                                         {
7881                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
7882                                                 0u,                                                                                             // deUint32                             mipLevel;
7883                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
7884                                                 1u,                                                                                             // deUint32                             layerCount;
7885                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
7886                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
7887                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
7888                                 };
7889                         CopyRegion copyRegion;
7890                         copyRegion.bufferImageCopy = bufferImageCopy;
7891
7892                         params.regions.push_back(copyRegion);
7893                 }
7894                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
7895         }
7896 }
7897
7898 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7899 {
7900         tcu::TestContext& testCtx = group->getTestContext();
7901
7902         const struct
7903         {
7904                 const char*             name;
7905                 const VkFormat  format;
7906         } depthAndStencilFormats[] =
7907         {
7908                 { "d16_unorm",                          VK_FORMAT_D16_UNORM                             },
7909                 { "x8_d24_unorm_pack32",        VK_FORMAT_X8_D24_UNORM_PACK32   },
7910                 { "d32_sfloat",                         VK_FORMAT_D32_SFLOAT                    },
7911                 { "d16_unorm_s8_uint",          VK_FORMAT_D16_UNORM_S8_UINT             },
7912                 { "d24_unorm_s8_uint",          VK_FORMAT_D24_UNORM_S8_UINT             },
7913                 { "d32_sfloat_s8_uint",         VK_FORMAT_D32_SFLOAT_S8_UINT    }
7914         };
7915
7916         const VkImageSubresourceLayers  depthSourceLayer                =
7917         {
7918                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
7919                 0u,                                                     // deUint32                             mipLevel;
7920                 0u,                                                     // deUint32                             baseArrayLayer;
7921                 1u,                                                     // deUint32                             layerCount;
7922         };
7923
7924         const VkBufferImageCopy                 bufferDepthCopy                 =
7925         {
7926                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
7927                 0u,                                                                                     // deUint32                                     bufferRowLength;
7928                 0u,                                                                                     // deUint32                                     bufferImageHeight;
7929                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
7930                 {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
7931                 defaultExtent                                                           // VkExtent3D                           imageExtent;
7932         };
7933
7934         const VkBufferImageCopy                 bufferDepthCopyOffset   =
7935         {
7936                 32,                                                                                     // VkDeviceSize                         bufferOffset;
7937                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
7938                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
7939                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
7940                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7941                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7942         };
7943
7944         const VkImageSubresourceLayers  stencilSourceLayer              =
7945         {
7946                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
7947                 0u,                                                             // deUint32                             mipLevel;
7948                 0u,                                                             // deUint32                             baseArrayLayer;
7949                 1u,                                                             // deUint32                             layerCount;
7950         };
7951
7952         const VkBufferImageCopy                 bufferStencilCopy               =
7953         {
7954                 0u,                                     // VkDeviceSize                         bufferOffset;
7955                 0u,                                     // deUint32                                     bufferRowLength;
7956                 0u,                                     // deUint32                                     bufferImageHeight;
7957                 stencilSourceLayer,     // VkImageSubresourceLayers     imageSubresource;
7958                 {0, 0, 0},                      // VkOffset3D                           imageOffset;
7959                 defaultExtent           // VkExtent3D                           imageExtent;
7960         };
7961
7962     const VkBufferImageCopy                     bufferStencilCopyOffset =
7963         {
7964                 32,                                                                                     // VkDeviceSize                         bufferOffset;
7965                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
7966                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
7967                 stencilSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
7968                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
7969                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
7970         };
7971
7972     const bool                                          useOffset[]                             = {false, true};
7973
7974         // Note: Depth stencil tests I want to do
7975         // Formats: D16, D24S8, D32FS8
7976         // Test writing each component with separate CopyBufferToImage commands
7977         // Test writing both components in one CopyBufferToImage command
7978         // Swap order of writes of Depth & Stencil
7979         // whole surface, subimages?
7980         // Similar tests as BufferToImage?
7981         for (const auto config : depthAndStencilFormats)
7982                 for (const auto offset : useOffset)
7983                 {
7984                         // TODO: Check that this format is supported before creating tests?
7985                         //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
7986
7987                         CopyRegion                                      copyDepthRegion;
7988                         CopyRegion                                      copyStencilRegion;
7989                         TestParams                                      params;
7990                         const tcu::TextureFormat        format          = mapVkFormat(config.format);
7991                         const bool                                      hasDepth        = tcu::hasDepthComponent(format.order);
7992                         const bool                                      hasStencil      = tcu::hasStencilComponent(format.order);
7993                         std::string                                     description     = config.name;
7994
7995                         if (offset)
7996                         {
7997                                 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
7998                                 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
7999                                 description = "buffer_offset_" + description;
8000                                 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
8001                         }
8002                         else
8003                         {
8004                                 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
8005                                 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
8006                                 params.src.buffer.size = defaultSize * defaultSize;
8007                         }
8008
8009                         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8010                         params.dst.image.format = config.format;
8011                         params.dst.image.extent = defaultExtent;
8012                         params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8013                         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8014                         params.allocationKind = allocationKind;
8015                         params.extensionUse = extensionUse;
8016
8017                         if (hasDepth && hasStencil)
8018                         {
8019                                 params.singleCommand = DE_TRUE;
8020
8021                                 params.regions.push_back(copyDepthRegion);
8022                                 params.regions.push_back(copyStencilRegion);
8023
8024                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
8025
8026                                 params.singleCommand = DE_FALSE;
8027
8028                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
8029
8030                                 params.regions.clear();
8031                                 params.regions.push_back(copyStencilRegion);
8032                                 params.regions.push_back(copyDepthRegion);
8033
8034                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
8035
8036                                 params.singleCommand = DE_TRUE;
8037                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
8038                         }
8039
8040                         if (hasStencil)
8041                         {
8042                                 params.regions.clear();
8043                                 params.regions.push_back(copyStencilRegion);
8044
8045                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
8046                         }
8047
8048                         if (hasDepth)
8049                         {
8050                                 params.regions.clear();
8051                                 params.regions.push_back(copyDepthRegion);
8052
8053                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
8054                         }
8055                 }
8056 }
8057
8058 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8059 {
8060         tcu::TestContext& testCtx       = group->getTestContext();
8061
8062         {
8063                 TestParams      params;
8064                 params.src.buffer.size                          = defaultSize * defaultSize;
8065                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8066                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
8067                 params.dst.image.extent                         = defaultExtent;
8068                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8069                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8070                 params.allocationKind                           = allocationKind;
8071                 params.extensionUse                                     = extensionUse;
8072
8073                 const VkBufferImageCopy bufferImageCopy =
8074                 {
8075                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
8076                         0u,                                                                                     // deUint32                                     bufferRowLength;
8077                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8078                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8079                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
8080                         defaultExtent                                                           // VkExtent3D                           imageExtent;
8081                 };
8082                 CopyRegion      copyRegion;
8083                 copyRegion.bufferImageCopy      = bufferImageCopy;
8084
8085                 params.regions.push_back(copyRegion);
8086
8087                 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
8088         }
8089
8090         {
8091                 TestParams      params;
8092                 params.src.buffer.size                          = defaultSize * defaultSize;
8093                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8094                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8095                 params.dst.image.extent                         = defaultExtent;
8096                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8097                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8098                 params.allocationKind                           = allocationKind;
8099                 params.extensionUse                                     = extensionUse;
8100
8101                 CopyRegion      region;
8102                 deUint32        divisor = 1;
8103                 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
8104                 {
8105                         const VkBufferImageCopy bufferImageCopy =
8106                         {
8107                                 0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
8108                                 0u,                                                                                                                             // deUint32                                     bufferRowLength;
8109                                 0u,                                                                                                                             // deUint32                                     bufferImageHeight;
8110                                 defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
8111                                 {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
8112                                 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
8113                         };
8114                         region.bufferImageCopy  = bufferImageCopy;
8115                         params.regions.push_back(region);
8116                 }
8117
8118                 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
8119         }
8120
8121         {
8122                 TestParams      params;
8123                 params.src.buffer.size                          = defaultSize * defaultSize;
8124                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8125                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8126                 params.dst.image.extent                         = defaultExtent;
8127                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8128                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8129                 params.allocationKind                           = allocationKind;
8130                 params.extensionUse                                     = extensionUse;
8131
8132                 const VkBufferImageCopy bufferImageCopy =
8133                 {
8134                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
8135                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
8136                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
8137                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8138                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8139                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8140                 };
8141                 CopyRegion      copyRegion;
8142                 copyRegion.bufferImageCopy      = bufferImageCopy;
8143
8144                 params.regions.push_back(copyRegion);
8145
8146                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
8147         }
8148
8149         {
8150                 TestParams      params;
8151                 params.src.buffer.size                          = defaultSize * defaultSize;
8152                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8153                 params.dst.image.format                         = VK_FORMAT_R8_UNORM;
8154                 params.dst.image.extent                         = defaultExtent;
8155                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8156                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8157                 params.allocationKind                           = allocationKind;
8158                 params.extensionUse                                     = extensionUse;
8159
8160                 const VkBufferImageCopy bufferImageCopy =
8161                 {
8162                         defaultFourthSize + 1u,                                         // VkDeviceSize                         bufferOffset;
8163                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
8164                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
8165                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8166                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8167                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8168                 };
8169                 CopyRegion      copyRegion;
8170                 copyRegion.bufferImageCopy      = bufferImageCopy;
8171
8172                 params.regions.push_back(copyRegion);
8173
8174                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
8175         }
8176
8177         {
8178                 TestParams                              params;
8179                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
8180                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8181                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8182                 params.dst.image.extent                         = defaultExtent;
8183                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8184                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8185                 params.allocationKind                           = allocationKind;
8186                 params.extensionUse                                     = extensionUse;
8187
8188                 const VkBufferImageCopy bufferImageCopy =
8189                 {
8190                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
8191                         defaultSize,                                                            // deUint32                                     bufferRowLength;
8192                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
8193                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8194                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8195                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8196                 };
8197                 CopyRegion                              copyRegion;
8198                 copyRegion.bufferImageCopy      = bufferImageCopy;
8199
8200                 params.regions.push_back(copyRegion);
8201
8202                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
8203         }
8204
8205         {
8206                 TestParams                              params;
8207                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
8208                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8209                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8210                 params.dst.image.extent                         = defaultExtent;
8211                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8212                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8213                 params.allocationKind                           = allocationKind;
8214                 params.extensionUse                                     = extensionUse;
8215
8216                 const VkBufferImageCopy bufferImageCopy =
8217                 {
8218                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
8219                         defaultSize,                                                            // deUint32                                     bufferRowLength;
8220                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
8221                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8222                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8223                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8224                 };
8225                 CopyRegion                              copyRegion;
8226                 copyRegion.bufferImageCopy      = bufferImageCopy;
8227
8228                 params.regions.push_back(copyRegion);
8229
8230                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
8231         }
8232
8233         {
8234                 TestParams                              params;
8235                 deUint32                                arrayLayers = 16u;
8236                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
8237                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8238                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8239                 params.dst.image.extent                         = defaultHalfExtent;
8240                 params.dst.image.extent.depth           = arrayLayers;
8241                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8242                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8243                 params.allocationKind                           = allocationKind;
8244                 params.extensionUse                                     = extensionUse;
8245
8246                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
8247                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
8248                 {
8249                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
8250                         const VkBufferImageCopy bufferImageCopy =
8251                                 {
8252                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
8253                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
8254                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
8255                                         {
8256                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
8257                                                 0u,                                                                                             // deUint32                             mipLevel;
8258                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
8259                                                 1u,                                                                                             // deUint32                             layerCount;
8260                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
8261                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
8262                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
8263                                 };
8264                         CopyRegion copyRegion;
8265                         copyRegion.bufferImageCopy = bufferImageCopy;
8266
8267                         params.regions.push_back(copyRegion);
8268                 }
8269                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
8270         }
8271
8272         {
8273                 TestParams                              params;
8274                 deUint32                                arrayLayers = 16u;
8275                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
8276                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8277                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8278                 params.dst.image.extent                         = defaultHalfExtent;
8279                 params.dst.image.extent.depth           = arrayLayers;
8280                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8281                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8282                 params.allocationKind                           = allocationKind;
8283                 params.extensionUse                                     = extensionUse;
8284
8285                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
8286                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
8287                 {
8288                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
8289                         const VkBufferImageCopy bufferImageCopy =
8290                                 {
8291                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
8292                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
8293                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
8294                                         {
8295                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
8296                                                 0u,                                                                                             // deUint32                             mipLevel;
8297                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
8298                                                 1u,                                                                                             // deUint32                             layerCount;
8299                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
8300                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
8301                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
8302                                 };
8303                         CopyRegion copyRegion;
8304                         copyRegion.bufferImageCopy = bufferImageCopy;
8305
8306                         params.regions.push_back(copyRegion);
8307                 }
8308                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
8309         }
8310 }
8311
8312 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8313 {
8314         tcu::TestContext&                               testCtx                                 = group->getTestContext();
8315
8316         {
8317                 TestParams                      params;
8318                 params.src.buffer.size  = defaultSize;
8319                 params.dst.buffer.size  = defaultSize;
8320                 params.allocationKind   = allocationKind;
8321                 params.extensionUse             = extensionUse;
8322
8323                 const VkBufferCopy      bufferCopy      =
8324                 {
8325                         0u,                             // VkDeviceSize srcOffset;
8326                         0u,                             // VkDeviceSize dstOffset;
8327                         defaultSize,    // VkDeviceSize size;
8328                 };
8329
8330                 CopyRegion      copyRegion;
8331                 copyRegion.bufferCopy   = bufferCopy;
8332                 params.regions.push_back(copyRegion);
8333
8334                 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
8335         }
8336
8337         // Filter is VK_FILTER_NEAREST.
8338         {
8339                 TestParams                      params;
8340                 params.src.buffer.size  = defaultFourthSize;
8341                 params.dst.buffer.size  = defaultFourthSize;
8342                 params.allocationKind   = allocationKind;
8343                 params.extensionUse             = extensionUse;
8344
8345                 const VkBufferCopy      bufferCopy      =
8346                 {
8347                         12u,    // VkDeviceSize srcOffset;
8348                         4u,             // VkDeviceSize dstOffset;
8349                         1u,             // VkDeviceSize size;
8350                 };
8351
8352                 CopyRegion      copyRegion;
8353                 copyRegion.bufferCopy = bufferCopy;
8354                 params.regions.push_back(copyRegion);
8355
8356                 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
8357         }
8358
8359         {
8360                 const deUint32          size            = 16;
8361                 TestParams                      params;
8362                 params.src.buffer.size  = size;
8363                 params.dst.buffer.size  = size * (size + 1);
8364                 params.allocationKind   = allocationKind;
8365                 params.extensionUse             = extensionUse;
8366
8367                 // Copy region with size 1..size
8368                 for (unsigned int i = 1; i <= size; i++)
8369                 {
8370                         const VkBufferCopy      bufferCopy      =
8371                         {
8372                                 0,                      // VkDeviceSize srcOffset;
8373                                 i * size,       // VkDeviceSize dstOffset;
8374                                 i,                      // VkDeviceSize size;
8375                         };
8376
8377                         CopyRegion      copyRegion;
8378                         copyRegion.bufferCopy = bufferCopy;
8379                         params.regions.push_back(copyRegion);
8380                 }
8381
8382                 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
8383         }
8384 }
8385
8386 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
8387 {
8388         tcu::TestContext& testCtx = group->getTestContext();
8389
8390         // Filter is VK_FILTER_NEAREST.
8391         {
8392                 params.filter                                   = VK_FILTER_NEAREST;
8393                 const std::string description   = "Nearest filter";
8394
8395                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
8396                 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
8397
8398                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
8399                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
8400                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
8401
8402                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
8403                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
8404                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
8405         }
8406
8407         // Filter is VK_FILTER_LINEAR.
8408         {
8409                 params.filter                                   = VK_FILTER_LINEAR;
8410                 const std::string description   = "Linear filter";
8411
8412                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
8413                 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
8414
8415                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
8416                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
8417                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
8418
8419                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
8420                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
8421                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
8422         }
8423
8424         // Filter is VK_FILTER_CUBIC_EXT.
8425         // Cubic filtering can only be used with 2D images.
8426         if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
8427         {
8428                 params.filter                                   = VK_FILTER_CUBIC_EXT;
8429                 const std::string description   = "Cubic filter";
8430
8431                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
8432                 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
8433
8434                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
8435                 const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
8436                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
8437
8438                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
8439                 const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
8440                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
8441         }
8442 }
8443
8444 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
8445 {
8446         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8447         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8448         params.src.image.extent                 = defaultExtent;
8449         params.dst.image.extent                 = defaultExtent;
8450         params.src.image.extent.depth   = imageDepth;
8451         params.dst.image.extent.depth   = imageDepth;
8452
8453         {
8454                 const VkImageBlit imageBlit =
8455                 {
8456                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8457                         {
8458                                 { 0, 0, 0 },
8459                                 { defaultSize, defaultSize, imageDepth }
8460                         },                                      // VkOffset3D                           srcOffsets[2];
8461
8462                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8463                         {
8464                                 { 0, 0, 0 },
8465                                 { defaultSize, defaultSize, imageDepth }
8466                         }                                       // VkOffset3D                           dstOffset[2];
8467                 };
8468
8469                 CopyRegion region;
8470                 region.imageBlit = imageBlit;
8471                 params.regions.push_back(region);
8472         }
8473
8474         addBlittingImageSimpleTests(group, params);
8475 }
8476
8477 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
8478 {
8479         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8480         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8481         params.src.image.extent                 = defaultExtent;
8482         params.dst.image.extent                 = defaultExtent;
8483         params.src.image.extent.depth   = imageDepth;
8484         params.dst.image.extent.depth   = imageDepth;
8485
8486         {
8487                 const VkImageBlit imageBlit =
8488                 {
8489                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8490                         {
8491                                 {0, 0, 0},
8492                                 {defaultSize, defaultSize, imageDepth}
8493                         },                                      // VkOffset3D                           srcOffsets[2];
8494
8495                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8496                         {
8497                                 {defaultSize, defaultSize, 0},
8498                                 {0, 0, imageDepth}
8499                         }                                       // VkOffset3D                           dstOffset[2];
8500                 };
8501
8502                 CopyRegion region;
8503                 region.imageBlit = imageBlit;
8504                 params.regions.push_back(region);
8505         }
8506
8507         addBlittingImageSimpleTests(group, params);
8508 }
8509
8510 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
8511 {
8512         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8513         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8514         params.src.image.extent                 = defaultExtent;
8515         params.dst.image.extent                 = defaultExtent;
8516         params.src.image.extent.depth   = imageDepth;
8517         params.dst.image.extent.depth   = imageDepth;
8518
8519         {
8520                 const VkImageBlit imageBlit =
8521                 {
8522                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8523                         {
8524                                 {0, 0, 0},
8525                                 {defaultSize, defaultSize, imageDepth}
8526                         },                                      // VkOffset3D                           srcOffsets[2];
8527
8528                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8529                         {
8530                                 {defaultSize, 0, 0},
8531                                 {0, defaultSize, imageDepth}
8532                         }                                       // VkOffset3D                           dstOffset[2];
8533                 };
8534
8535                 CopyRegion region;
8536                 region.imageBlit = imageBlit;
8537                 params.regions.push_back(region);
8538         }
8539
8540         addBlittingImageSimpleTests(group, params);
8541 }
8542
8543 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
8544 {
8545         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8546         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8547         params.src.image.extent                 = defaultExtent;
8548         params.dst.image.extent                 = defaultExtent;
8549         params.src.image.extent.depth   = imageDepth;
8550         params.dst.image.extent.depth   = imageDepth;
8551
8552         {
8553                 const VkImageBlit imageBlit =
8554                 {
8555                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8556                         {
8557                                 {0, 0, 0},
8558                                 {defaultSize, defaultSize, imageDepth}
8559                         },                                      // VkOffset3D                           srcOffsets[2];
8560
8561                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8562                         {
8563                                 {0, defaultSize, 0},
8564                                 {defaultSize, 0, imageDepth}
8565                         }                                       // VkOffset3D                           dstOffset[2];
8566                 };
8567
8568                 CopyRegion region;
8569                 region.imageBlit = imageBlit;
8570                 params.regions.push_back(region);
8571         }
8572
8573         addBlittingImageSimpleTests(group, params);
8574 }
8575
8576 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
8577 {
8578         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8579         DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
8580         params.src.image.extent                 = defaultExtent;
8581         params.dst.image.extent                 = defaultExtent;
8582         params.src.image.extent.depth   = defaultSize;
8583         params.dst.image.extent.depth   = defaultSize;
8584
8585         {
8586                 const VkImageBlit imageBlit =
8587                 {
8588                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8589                         {
8590                                 {0, 0, 0},
8591                                 {defaultSize, defaultSize, defaultSize}
8592                         },                                      // VkOffset3D                           srcOffsets[2];
8593
8594                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8595                         {
8596                                 {0, 0, defaultSize},
8597                                 {defaultSize, defaultSize, 0}
8598                         }                                       // VkOffset3D                           dstOffset[2];
8599                 };
8600
8601                 CopyRegion region;
8602                 region.imageBlit = imageBlit;
8603                 params.regions.push_back(region);
8604         }
8605
8606         addBlittingImageSimpleTests(group, params);
8607 }
8608
8609 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
8610 {
8611         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8612         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8613         params.src.image.extent                 = defaultExtent;
8614         params.dst.image.extent                 = defaultExtent;
8615         params.src.image.extent.depth   = imageDepth;
8616         params.dst.image.extent.depth   = imageDepth;
8617
8618         // No mirroring.
8619         {
8620                 const VkImageBlit imageBlit =
8621                 {
8622                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8623                         {
8624                                 {0, 0, 0},
8625                                 {defaultHalfSize, defaultHalfSize, imageDepth}
8626                         },                                      // VkOffset3D                           srcOffsets[2];
8627
8628                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8629                         {
8630                                 {0, 0, 0},
8631                                 {defaultHalfSize, defaultHalfSize, imageDepth}
8632                         }                                       // VkOffset3D                           dstOffset[2];
8633                 };
8634
8635                 CopyRegion region;
8636                 region.imageBlit = imageBlit;
8637                 params.regions.push_back(region);
8638         }
8639
8640         // Flipping y coordinates.
8641         {
8642                 const VkImageBlit imageBlit =
8643                 {
8644                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8645                         {
8646                                 {defaultHalfSize, 0, 0},
8647                                 {defaultSize, defaultHalfSize, imageDepth}
8648                         },                                      // VkOffset3D                           srcOffsets[2];
8649
8650                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8651                         {
8652                                 {defaultHalfSize, defaultHalfSize, 0},
8653                                 {defaultSize, 0, imageDepth}
8654                         }                                       // VkOffset3D                           dstOffset[2];
8655                 };
8656                 CopyRegion region;
8657                 region.imageBlit = imageBlit;
8658                 params.regions.push_back(region);
8659         }
8660
8661         // Flipping x coordinates.
8662         {
8663                 const VkImageBlit imageBlit =
8664                 {
8665                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8666                         {
8667                                 {0, defaultHalfSize, 0},
8668                                 {defaultHalfSize, defaultSize, imageDepth}
8669                         },                                      // VkOffset3D                           srcOffsets[2];
8670
8671                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8672                         {
8673                                 {defaultHalfSize, defaultHalfSize, 0},
8674                                 {0, defaultSize, imageDepth}
8675                         }                                       // VkOffset3D                           dstOffset[2];
8676                 };
8677
8678                 CopyRegion region;
8679                 region.imageBlit = imageBlit;
8680                 params.regions.push_back(region);
8681         }
8682
8683         // Flipping x and y coordinates.
8684         {
8685                 const VkImageBlit imageBlit =
8686                 {
8687                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8688                         {
8689                                 {defaultHalfSize, defaultHalfSize, 0},
8690                                 {defaultSize, defaultSize, imageDepth}
8691                         },                                      // VkOffset3D                           srcOffsets[2];
8692
8693                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8694                         {
8695                                 {defaultSize, defaultSize, 0},
8696                                 {defaultHalfSize, defaultHalfSize, imageDepth}
8697                         }                                       // VkOffset3D                           dstOffset[2];
8698                 };
8699
8700                 CopyRegion region;
8701                 region.imageBlit = imageBlit;
8702                 params.regions.push_back(region);
8703         }
8704
8705         addBlittingImageSimpleTests(group, params);
8706 }
8707
8708 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
8709 {
8710         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8711         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8712         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
8713         params.src.image.extent                 = defaultExtent;
8714         params.dst.image.extent                 = defaultHalfExtent;
8715         params.src.image.extent.depth   = imageDepth;
8716         params.dst.image.extent.depth   = halfImageDepth;
8717
8718         {
8719                 const VkImageBlit imageBlit =
8720                 {
8721                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8722                         {
8723                                 {0, 0, 0},
8724                                 {defaultSize, defaultSize, imageDepth}
8725                         },                                      // VkOffset3D                                   srcOffsets[2];
8726
8727                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8728                         {
8729                                 {0, 0, 0},
8730                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
8731                         }                                       // VkOffset3D                                   dstOffset[2];
8732                 };
8733
8734                 CopyRegion region;
8735                 region.imageBlit = imageBlit;
8736                 params.regions.push_back(region);
8737         }
8738
8739         addBlittingImageSimpleTests(group, params);
8740 }
8741
8742 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
8743 {
8744         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8745         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8746         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
8747         params.src.image.extent                 = defaultHalfExtent;
8748         params.dst.image.extent                 = defaultExtent;
8749         params.src.image.extent.depth   = halfImageDepth;
8750         params.dst.image.extent.depth   = imageDepth;
8751
8752         {
8753                 const VkImageBlit imageBlit =
8754                 {
8755                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8756                         {
8757                                 {0, 0, 0},
8758                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
8759                         },                                      // VkOffset3D                                   srcOffsets[2];
8760
8761                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8762                         {
8763                                 {0, 0, 0},
8764                                 {defaultSize, defaultSize, imageDepth}
8765                         }                                       // VkOffset3D                                   dstOffset[2];
8766                 };
8767
8768                 CopyRegion region;
8769                 region.imageBlit = imageBlit;
8770                 params.regions.push_back(region);
8771         }
8772
8773         addBlittingImageSimpleTests(group, params);
8774 }
8775
8776 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
8777 {
8778         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8779         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
8780         const deInt32   srcDepthOffset  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
8781         const deInt32   srcDepthSize    = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
8782         params.src.image.extent                 = defaultExtent;
8783         params.dst.image.extent                 = defaultExtent;
8784         params.src.image.extent.depth   = imageDepth;
8785         params.dst.image.extent.depth   = imageDepth;
8786
8787         {
8788                 const VkImageBlit imageBlit =
8789                 {
8790                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8791                         {
8792                                 {defaultFourthSize, defaultFourthSize, srcDepthOffset},
8793                                 {defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
8794                         },                                      // VkOffset3D                                   srcOffsets[2];
8795
8796                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8797                         {
8798                                 {0, 0, 0},
8799                                 {defaultSize, defaultSize, imageDepth}
8800                         }                                       // VkOffset3D                                   dstOffset[2];
8801                 };
8802
8803                 CopyRegion region;
8804                 region.imageBlit = imageBlit;
8805                 params.regions.push_back(region);
8806         }
8807
8808         addBlittingImageSimpleTests(group, params);
8809 }
8810
8811 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
8812 {
8813         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
8814         const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
8815         params.src.image.extent = defaultExtent;
8816         params.dst.image.extent = defaultExtent;
8817
8818         if (is3dBlit)
8819         {
8820                 params.src.image.extent.depth = defaultSize;
8821                 params.dst.image.extent.depth = defaultSize;
8822         }
8823
8824         {
8825                 CopyRegion region;
8826                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
8827                 {
8828                         const VkImageBlit imageBlit =
8829                         {
8830                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
8831                                 {
8832                                         {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
8833                                         {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
8834                                 },                                      // VkOffset3D                                   srcOffsets[2];
8835
8836                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
8837                                 {
8838                                         {i, i, is3dBlit ? i : 0},
8839                                         {i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
8840                                 }                                       // VkOffset3D                                   dstOffset[2];
8841                         };
8842                         region.imageBlit = imageBlit;
8843                         params.regions.push_back(region);
8844                 }
8845         }
8846
8847         addBlittingImageSimpleTests(group, params);
8848 }
8849
8850 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8851 {
8852         TestParams params;
8853         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8854         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8855         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8856         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8857         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8858         params.allocationKind                           = allocationKind;
8859         params.extensionUse                                     = extensionUse;
8860         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8861         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
8862         addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
8863         addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
8864         addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
8865         addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
8866         addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
8867         addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
8868         addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
8869         addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
8870         addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
8871
8872         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
8873         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
8874         addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
8875         addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
8876         addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
8877         addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
8878         addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
8879         addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
8880         addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
8881         addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
8882         addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
8883         addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
8884 }
8885
8886 enum FilterMaskBits
8887 {
8888         FILTER_MASK_NEAREST     = 0,                    // Always tested.
8889         FILTER_MASK_LINEAR      = (1u << 0),
8890         FILTER_MASK_CUBIC       = (1u << 1),
8891 };
8892
8893 using FilterMask = deUint32;
8894
8895 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
8896 {
8897         FilterMask mask = FILTER_MASK_NEAREST;
8898
8899         if (!onlyNearest)
8900         {
8901                 mask |= FILTER_MASK_LINEAR;
8902                 if (!discardCubicFilter)
8903                         mask |= FILTER_MASK_CUBIC;
8904         }
8905
8906         return mask;
8907 }
8908
8909 struct BlitColorTestParams
8910 {
8911         TestParams              params;
8912         const VkFormat* compatibleFormats;
8913         FilterMask              testFilters;
8914 };
8915
8916 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
8917 {
8918         bool result = true;
8919
8920         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
8921         {
8922                 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
8923
8924                 result =
8925                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
8926                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
8927         }
8928
8929         return result;
8930 }
8931
8932 const VkFormat  linearOtherImageFormatsToTest[] =
8933 {
8934         // From compatibleFormats8Bit
8935         VK_FORMAT_R4G4_UNORM_PACK8,
8936         VK_FORMAT_R8_SRGB,
8937
8938         // From compatibleFormats16Bit
8939         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
8940         VK_FORMAT_R16_SFLOAT,
8941
8942         // From compatibleFormats24Bit
8943         VK_FORMAT_R8G8B8_UNORM,
8944         VK_FORMAT_B8G8R8_SRGB,
8945
8946         // From compatibleFormats32Bit
8947         VK_FORMAT_R8G8B8A8_UNORM,
8948         VK_FORMAT_R32_SFLOAT,
8949
8950         // From compatibleFormats48Bit
8951         VK_FORMAT_R16G16B16_UNORM,
8952         VK_FORMAT_R16G16B16_SFLOAT,
8953
8954         // From compatibleFormats64Bit
8955         VK_FORMAT_R16G16B16A16_UNORM,
8956         VK_FORMAT_R64_SFLOAT,
8957
8958         // From compatibleFormats96Bit
8959         VK_FORMAT_R32G32B32_UINT,
8960         VK_FORMAT_R32G32B32_SFLOAT,
8961
8962         // From compatibleFormats128Bit
8963         VK_FORMAT_R32G32B32A32_UINT,
8964         VK_FORMAT_R64G64_SFLOAT,
8965
8966         // From compatibleFormats192Bit
8967         VK_FORMAT_R64G64B64_UINT,
8968         VK_FORMAT_R64G64B64_SFLOAT,
8969
8970         // From compatibleFormats256Bit
8971         VK_FORMAT_R64G64B64A64_UINT,
8972         VK_FORMAT_R64G64B64A64_SFLOAT,
8973 };
8974
8975 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
8976 {
8977         switch (tiling)
8978         {
8979                 case VK_IMAGE_TILING_OPTIMAL:
8980                         return getImageLayoutCaseName(layout);
8981                 case VK_IMAGE_TILING_LINEAR:
8982                         return "linear";
8983                 default:
8984                         DE_ASSERT(false);
8985                         return "";
8986         }
8987 }
8988
8989 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
8990 {
8991         tcu::TestContext& testCtx                               = group->getTestContext();
8992
8993         FormatSet linearOtherImageFormatsToTestSet;
8994         const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
8995         for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
8996                 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
8997
8998         const VkImageTiling blitSrcTilings[]    =
8999         {
9000                 VK_IMAGE_TILING_OPTIMAL,
9001                 VK_IMAGE_TILING_LINEAR,
9002         };
9003         const VkImageLayout blitSrcLayouts[]    =
9004         {
9005                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9006                 VK_IMAGE_LAYOUT_GENERAL
9007         };
9008         const VkImageTiling blitDstTilings[]    =
9009         {
9010                 VK_IMAGE_TILING_OPTIMAL,
9011                 VK_IMAGE_TILING_LINEAR,
9012         };
9013         const VkImageLayout blitDstLayouts[]    =
9014         {
9015                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9016                 VK_IMAGE_LAYOUT_GENERAL
9017         };
9018
9019         for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
9020         {
9021                 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
9022
9023                 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
9024                 {
9025                         testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
9026
9027                         // 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
9028                         if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
9029                                 continue;
9030
9031                         for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
9032                         {
9033                                 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
9034
9035                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
9036                                 {
9037                                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
9038
9039                                         // 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
9040                                         if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
9041                                                 continue;
9042
9043                                         if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
9044                                             (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
9045                                                 continue;
9046
9047                                         testParams.params.filter                        = VK_FILTER_NEAREST;
9048                                         const std::string testName                      = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
9049                                                                                                                   getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
9050                                         const std::string description           = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
9051                                                                                                                   " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
9052                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
9053
9054                                         if (testParams.testFilters & FILTER_MASK_LINEAR)
9055                                         {
9056                                                 testParams.params.filter = VK_FILTER_LINEAR;
9057                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
9058                                         }
9059
9060                                         if (testParams.testFilters & FILTER_MASK_CUBIC)
9061                                         {
9062                                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
9063                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
9064                                         }
9065
9066                                         if (testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D)
9067                                         {
9068                                                 const struct
9069                                                 {
9070                                                         FillMode        mode;
9071                                                         const char*     name;
9072                                                 } modeList[] =
9073                                                 {
9074                                                         { FILL_MODE_BLUE_RED_X, "x" },
9075                                                         { FILL_MODE_BLUE_RED_Y, "y" },
9076                                                         { FILL_MODE_BLUE_RED_Z, "z" },
9077                                                 };
9078
9079                                                 auto otherParams = testParams;
9080                                                 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
9081
9082                                                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
9083                                                 {
9084                                                         otherParams.params.src.image.fillMode = modeList[i].mode;
9085
9086                                                         otherParams.params.filter = VK_FILTER_LINEAR;
9087                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
9088
9089                                                         otherParams.params.filter = VK_FILTER_NEAREST;
9090                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
9091                                                 }
9092                                         }
9093                                 }
9094                         }
9095                 }
9096         }
9097 }
9098
9099 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
9100 {
9101         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
9102         const VkFormat  srcFormatOnly[2]        = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
9103         const VkFormat* formatList                      = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
9104
9105         for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
9106         {
9107                 testParams.params.dst.image.format      = formatList[dstFormatIndex];
9108                 if (!isSupportedByFramework(testParams.params.dst.image.format))
9109                         continue;
9110
9111                 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
9112                         continue;
9113
9114                 const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
9115                 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
9116         }
9117 }
9118
9119 const VkFormat  compatibleFormatsUInts[]        =
9120 {
9121         VK_FORMAT_R8_UINT,
9122         VK_FORMAT_R8G8_UINT,
9123         VK_FORMAT_R8G8B8_UINT,
9124         VK_FORMAT_B8G8R8_UINT,
9125         VK_FORMAT_R8G8B8A8_UINT,
9126         VK_FORMAT_B8G8R8A8_UINT,
9127         VK_FORMAT_A8B8G8R8_UINT_PACK32,
9128         VK_FORMAT_A2R10G10B10_UINT_PACK32,
9129         VK_FORMAT_A2B10G10R10_UINT_PACK32,
9130         VK_FORMAT_R16_UINT,
9131         VK_FORMAT_R16G16_UINT,
9132         VK_FORMAT_R16G16B16_UINT,
9133         VK_FORMAT_R16G16B16A16_UINT,
9134         VK_FORMAT_R32_UINT,
9135         VK_FORMAT_R32G32_UINT,
9136         VK_FORMAT_R32G32B32_UINT,
9137         VK_FORMAT_R32G32B32A32_UINT,
9138         VK_FORMAT_R64_UINT,
9139         VK_FORMAT_R64G64_UINT,
9140         VK_FORMAT_R64G64B64_UINT,
9141         VK_FORMAT_R64G64B64A64_UINT,
9142
9143         VK_FORMAT_UNDEFINED
9144 };
9145 const VkFormat  compatibleFormatsSInts[]        =
9146 {
9147         VK_FORMAT_R8_SINT,
9148         VK_FORMAT_R8G8_SINT,
9149         VK_FORMAT_R8G8B8_SINT,
9150         VK_FORMAT_B8G8R8_SINT,
9151         VK_FORMAT_R8G8B8A8_SINT,
9152         VK_FORMAT_B8G8R8A8_SINT,
9153         VK_FORMAT_A8B8G8R8_SINT_PACK32,
9154         VK_FORMAT_A2R10G10B10_SINT_PACK32,
9155         VK_FORMAT_A2B10G10R10_SINT_PACK32,
9156         VK_FORMAT_R16_SINT,
9157         VK_FORMAT_R16G16_SINT,
9158         VK_FORMAT_R16G16B16_SINT,
9159         VK_FORMAT_R16G16B16A16_SINT,
9160         VK_FORMAT_R32_SINT,
9161         VK_FORMAT_R32G32_SINT,
9162         VK_FORMAT_R32G32B32_SINT,
9163         VK_FORMAT_R32G32B32A32_SINT,
9164         VK_FORMAT_R64_SINT,
9165         VK_FORMAT_R64G64_SINT,
9166         VK_FORMAT_R64G64B64_SINT,
9167         VK_FORMAT_R64G64B64A64_SINT,
9168
9169         VK_FORMAT_UNDEFINED
9170 };
9171 const VkFormat  compatibleFormatsFloats[]       =
9172 {
9173         VK_FORMAT_R4G4_UNORM_PACK8,
9174         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9175         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
9176         VK_FORMAT_R5G6B5_UNORM_PACK16,
9177         VK_FORMAT_B5G6R5_UNORM_PACK16,
9178         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
9179         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
9180         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
9181         VK_FORMAT_R8_UNORM,
9182         VK_FORMAT_R8_SNORM,
9183         VK_FORMAT_R8_USCALED,
9184         VK_FORMAT_R8_SSCALED,
9185         VK_FORMAT_R8G8_UNORM,
9186         VK_FORMAT_R8G8_SNORM,
9187         VK_FORMAT_R8G8_USCALED,
9188         VK_FORMAT_R8G8_SSCALED,
9189         VK_FORMAT_R8G8B8_UNORM,
9190         VK_FORMAT_R8G8B8_SNORM,
9191         VK_FORMAT_R8G8B8_USCALED,
9192         VK_FORMAT_R8G8B8_SSCALED,
9193         VK_FORMAT_B8G8R8_UNORM,
9194         VK_FORMAT_B8G8R8_SNORM,
9195         VK_FORMAT_B8G8R8_USCALED,
9196         VK_FORMAT_B8G8R8_SSCALED,
9197         VK_FORMAT_R8G8B8A8_UNORM,
9198         VK_FORMAT_R8G8B8A8_SNORM,
9199         VK_FORMAT_R8G8B8A8_USCALED,
9200         VK_FORMAT_R8G8B8A8_SSCALED,
9201         VK_FORMAT_B8G8R8A8_UNORM,
9202         VK_FORMAT_B8G8R8A8_SNORM,
9203         VK_FORMAT_B8G8R8A8_USCALED,
9204         VK_FORMAT_B8G8R8A8_SSCALED,
9205         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9206         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9207         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9208         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9209         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9210         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9211         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9212         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9213         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9214         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9215         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9216         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9217         VK_FORMAT_R16_UNORM,
9218         VK_FORMAT_R16_SNORM,
9219         VK_FORMAT_R16_USCALED,
9220         VK_FORMAT_R16_SSCALED,
9221         VK_FORMAT_R16_SFLOAT,
9222         VK_FORMAT_R16G16_UNORM,
9223         VK_FORMAT_R16G16_SNORM,
9224         VK_FORMAT_R16G16_USCALED,
9225         VK_FORMAT_R16G16_SSCALED,
9226         VK_FORMAT_R16G16_SFLOAT,
9227         VK_FORMAT_R16G16B16_UNORM,
9228         VK_FORMAT_R16G16B16_SNORM,
9229         VK_FORMAT_R16G16B16_USCALED,
9230         VK_FORMAT_R16G16B16_SSCALED,
9231         VK_FORMAT_R16G16B16_SFLOAT,
9232         VK_FORMAT_R16G16B16A16_UNORM,
9233         VK_FORMAT_R16G16B16A16_SNORM,
9234         VK_FORMAT_R16G16B16A16_USCALED,
9235         VK_FORMAT_R16G16B16A16_SSCALED,
9236         VK_FORMAT_R16G16B16A16_SFLOAT,
9237         VK_FORMAT_R32_SFLOAT,
9238         VK_FORMAT_R32G32_SFLOAT,
9239         VK_FORMAT_R32G32B32_SFLOAT,
9240         VK_FORMAT_R32G32B32A32_SFLOAT,
9241         VK_FORMAT_R64_SFLOAT,
9242         VK_FORMAT_R64G64_SFLOAT,
9243         VK_FORMAT_R64G64B64_SFLOAT,
9244         VK_FORMAT_R64G64B64A64_SFLOAT,
9245         VK_FORMAT_B10G11R11_UFLOAT_PACK32,
9246         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
9247 //      VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9248 //      VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9249 //      VK_FORMAT_BC2_UNORM_BLOCK,
9250 //      VK_FORMAT_BC3_UNORM_BLOCK,
9251 //      VK_FORMAT_BC4_UNORM_BLOCK,
9252 //      VK_FORMAT_BC4_SNORM_BLOCK,
9253 //      VK_FORMAT_BC5_UNORM_BLOCK,
9254 //      VK_FORMAT_BC5_SNORM_BLOCK,
9255 //      VK_FORMAT_BC6H_UFLOAT_BLOCK,
9256 //      VK_FORMAT_BC6H_SFLOAT_BLOCK,
9257 //      VK_FORMAT_BC7_UNORM_BLOCK,
9258 //      VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9259 //      VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9260 //      VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9261 //      VK_FORMAT_EAC_R11_UNORM_BLOCK,
9262 //      VK_FORMAT_EAC_R11_SNORM_BLOCK,
9263 //      VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9264 //      VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9265 //      VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9266 //      VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9267 //      VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9268 //      VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9269 //      VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9270 //      VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9271 //      VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9272 //      VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9273 //      VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9274 //      VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9275 //      VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9276 //      VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9277 //      VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9278 //      VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9279
9280         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
9281         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
9282
9283         VK_FORMAT_UNDEFINED
9284 };
9285 const VkFormat  compatibleFormatsSrgb[]         =
9286 {
9287         VK_FORMAT_R8_SRGB,
9288         VK_FORMAT_R8G8_SRGB,
9289         VK_FORMAT_R8G8B8_SRGB,
9290         VK_FORMAT_B8G8R8_SRGB,
9291         VK_FORMAT_R8G8B8A8_SRGB,
9292         VK_FORMAT_B8G8R8A8_SRGB,
9293         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9294 //      VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9295 //      VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9296 //      VK_FORMAT_BC2_SRGB_BLOCK,
9297 //      VK_FORMAT_BC3_SRGB_BLOCK,
9298 //      VK_FORMAT_BC7_SRGB_BLOCK,
9299 //      VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9300 //      VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9301 //      VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9302 //      VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9303 //      VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9304 //      VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9305 //      VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9306 //      VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9307 //      VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9308 //      VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9309 //      VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9310 //      VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9311 //      VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9312 //      VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9313 //      VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9314 //      VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9315 //      VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9316
9317         VK_FORMAT_UNDEFINED
9318 };
9319
9320 const VkFormat  dedicatedAllocationBlittingFormatsToTest[]      =
9321 {
9322         // compatibleFormatsUInts
9323         VK_FORMAT_R8_UINT,
9324         VK_FORMAT_R64G64B64A64_UINT,
9325
9326         // compatibleFormatsSInts
9327         VK_FORMAT_R8_SINT,
9328         VK_FORMAT_R64G64B64A64_SINT,
9329
9330         // compatibleFormatsFloats
9331         VK_FORMAT_R4G4_UNORM_PACK8,
9332         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
9333
9334         // compatibleFormatsSrgb
9335         VK_FORMAT_R8_SRGB,
9336         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9337 };
9338
9339 // skip cubic filtering test for the following data formats
9340 const FormatSet onlyNearestAndLinearFormatsToTest =
9341 {
9342         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9343         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9344         VK_FORMAT_A8B8G8R8_UINT_PACK32,
9345         VK_FORMAT_A8B8G8R8_SINT_PACK32
9346 };
9347
9348 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9349 {
9350         const struct {
9351                 const VkFormat* compatibleFormats;
9352                 const bool              onlyNearest;
9353         }       colorImageFormatsToTestBlit[]                   =
9354         {
9355                 { compatibleFormatsUInts,       true    },
9356                 { compatibleFormatsSInts,       true    },
9357                 { compatibleFormatsFloats,      false   },
9358                 { compatibleFormatsSrgb,        false   },
9359         };
9360
9361         const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
9362
9363         if (allocationKind == ALLOCATION_KIND_DEDICATED)
9364         {
9365                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
9366                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
9367                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
9368         }
9369
9370         // 2D tests.
9371         {
9372                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
9373
9374                 TestParams      params;
9375                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
9376                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
9377                 params.src.image.extent         = defaultExtent;
9378                 params.dst.image.extent         = defaultExtent;
9379                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9380                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9381                 params.allocationKind           = allocationKind;
9382                 params.extensionUse                     = extensionUse;
9383
9384                 CopyRegion      region;
9385                 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
9386                 {
9387                         const VkImageBlit                       imageBlit       =
9388                         {
9389                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9390                                 {
9391                                         {0, 0, 0},
9392                                         {defaultSize, defaultSize, 1}
9393                                 },                                      // VkOffset3D                                   srcOffsets[2];
9394
9395                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9396                                 {
9397                                         {i, 0, 0},
9398                                         {i + defaultFourthSize / j, defaultFourthSize / j, 1}
9399                                 }                                       // VkOffset3D                                   dstOffset[2];
9400                         };
9401                         region.imageBlit        = imageBlit;
9402                         params.regions.push_back(region);
9403                 }
9404                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
9405                 {
9406                         const VkImageBlit                       imageBlit       =
9407                         {
9408                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9409                                 {
9410                                         {i, i, 0},
9411                                         {i + defaultFourthSize, i + defaultFourthSize, 1}
9412                                 },                                      // VkOffset3D                                   srcOffsets[2];
9413
9414                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9415                                 {
9416                                         {i, defaultSize / 2, 0},
9417                                         {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
9418                                 }                                       // VkOffset3D                                   dstOffset[2];
9419                         };
9420                         region.imageBlit        = imageBlit;
9421                         params.regions.push_back(region);
9422                 }
9423
9424                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9425                 {
9426                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
9427                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
9428                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9429                         {
9430                                 params.src.image.format = compatibleFormats[srcFormatIndex];
9431                                 if (!isSupportedByFramework(params.src.image.format))
9432                                         continue;
9433
9434                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
9435
9436                                 BlitColorTestParams             testParams;
9437                                 testParams.params                               = params;
9438                                 testParams.compatibleFormats    = compatibleFormats;
9439                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
9440
9441                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
9442                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
9443                         }
9444                 }
9445
9446                 group->addChild(subGroup.release());
9447         }
9448
9449         // 1D tests.
9450         {
9451                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
9452
9453                 TestParams      params;
9454                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
9455                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
9456                 params.src.image.extent         = default1dExtent;
9457                 params.dst.image.extent         = default1dExtent;
9458                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9459                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9460                 params.allocationKind           = allocationKind;
9461                 params.extensionUse                     = extensionUse;
9462
9463                 CopyRegion      region;
9464                 for (int i = 0; i < defaultSize; i += defaultSize / 2)
9465                 {
9466                         const VkImageBlit                       imageBlit       =
9467                         {
9468                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9469                                 {
9470                                         {0, 0, 0},
9471                                         {defaultSize, 1, 1}
9472                                 },                                      // VkOffset3D                                   srcOffsets[2];
9473
9474                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9475                                 {
9476                                         {i, 0, 0},
9477                                         {i + defaultFourthSize, 1, 1}
9478                                 }                                       // VkOffset3D                                   dstOffset[2];
9479                         };
9480                         region.imageBlit        = imageBlit;
9481                         params.regions.push_back(region);
9482                 }
9483
9484                 {
9485                         const VkImageBlit                       imageBlit       =
9486                         {
9487                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9488                                 {
9489                                         {0, 0, 0},
9490                                         {defaultFourthSize, 1, 1}
9491                                 },                                      // VkOffset3D                                   srcOffsets[2];
9492
9493                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9494                                 {
9495                                         {defaultFourthSize, 0, 0},
9496                                         {2 * defaultFourthSize, 1, 1}
9497                                 }                                       // VkOffset3D                                   dstOffset[2];
9498                         };
9499                         region.imageBlit        = imageBlit;
9500                         params.regions.push_back(region);
9501                 }
9502
9503                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9504                 {
9505                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
9506                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
9507                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9508                         {
9509                                 params.src.image.format = compatibleFormats[srcFormatIndex];
9510                                 if (!isSupportedByFramework(params.src.image.format))
9511                                         continue;
9512
9513                                 // Cubic filtering can only be used with 2D images.
9514                                 const bool onlyNearestAndLinear = true;
9515
9516                                 BlitColorTestParams     testParams;
9517                                 testParams.params                               = params;
9518                                 testParams.compatibleFormats    = nullptr;
9519                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
9520
9521                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
9522                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
9523                         }
9524                 }
9525
9526                 group->addChild(subGroup.release());
9527         }
9528
9529         // 3D tests. Note we use smaller dimensions here for performance reasons.
9530         {
9531                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
9532
9533                 TestParams      params;
9534                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
9535                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
9536                 params.src.image.extent         = default3dExtent;
9537                 params.dst.image.extent         = default3dExtent;
9538                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9539                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
9540                 params.allocationKind           = allocationKind;
9541                 params.extensionUse                     = extensionUse;
9542
9543                 CopyRegion      region;
9544                 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
9545                 {
9546                         const VkImageBlit                       imageBlit       =
9547                         {
9548                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9549                                 {
9550                                         {0, 0, 0},
9551                                         {defaultFourthSize, defaultFourthSize, defaultFourthSize}
9552                                 },                                      // VkOffset3D                                   srcOffsets[2];
9553
9554                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9555                                 {
9556                                         {i, 0, i},
9557                                         {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
9558                                 }                                       // VkOffset3D                                   dstOffset[2];
9559                         };
9560                         region.imageBlit        = imageBlit;
9561                         params.regions.push_back(region);
9562                 }
9563                 for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
9564                 {
9565                         const VkImageBlit                       imageBlit       =
9566                         {
9567                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9568                                 {
9569                                         {i, i, i},
9570                                         {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
9571                                 },                                      // VkOffset3D                                   srcOffsets[2];
9572
9573                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9574                                 {
9575                                         {i, defaultFourthSize / 2, i},
9576                                         {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
9577                                 }                                       // VkOffset3D                                   dstOffset[2];
9578                         };
9579                         region.imageBlit        = imageBlit;
9580                         params.regions.push_back(region);
9581                 }
9582
9583                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9584                 {
9585                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
9586                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
9587                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9588                         {
9589                                 params.src.image.format = compatibleFormats[srcFormatIndex];
9590                                 if (!isSupportedByFramework(params.src.image.format))
9591                                         continue;
9592
9593                                 // Cubic filtering can only be used with 2D images.
9594                                 const bool onlyNearestAndLinear = true;
9595
9596                                 BlitColorTestParams     testParams;
9597                                 testParams.params                               = params;
9598                                 testParams.compatibleFormats    = nullptr;
9599                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
9600
9601                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
9602                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
9603                         }
9604                 }
9605
9606                 group->addChild(subGroup.release());
9607         }
9608 }
9609
9610 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
9611 {
9612         const VkImageLayout blitSrcLayouts[]    =
9613         {
9614                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9615                 VK_IMAGE_LAYOUT_GENERAL
9616         };
9617         const VkImageLayout blitDstLayouts[]    =
9618         {
9619                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9620                 VK_IMAGE_LAYOUT_GENERAL
9621         };
9622
9623         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
9624         {
9625                 params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
9626
9627                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
9628                 {
9629                         params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
9630                         params.filter                                           = VK_FILTER_NEAREST;
9631
9632                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9633                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
9634                         const std::string description   = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
9635                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9636
9637                         group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
9638                 }
9639         }
9640 }
9641
9642 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9643 {
9644         const VkFormat  depthAndStencilFormats[]        =
9645         {
9646                 VK_FORMAT_D16_UNORM,
9647                 VK_FORMAT_X8_D24_UNORM_PACK32,
9648                 VK_FORMAT_D32_SFLOAT,
9649                 VK_FORMAT_S8_UINT,
9650                 VK_FORMAT_D16_UNORM_S8_UINT,
9651                 VK_FORMAT_D24_UNORM_S8_UINT,
9652                 VK_FORMAT_D32_SFLOAT_S8_UINT,
9653         };
9654
9655         const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9656         const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9657         const VkImageSubresourceLayers  defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9658
9659         // 2D tests
9660         {
9661                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
9662
9663                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9664                 {
9665                         TestParams      params;
9666                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9667                         params.src.image.extent                         = defaultExtent;
9668                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9669                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
9670                         params.dst.image.extent                         = defaultExtent;
9671                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9672                         params.dst.image.format                         = params.src.image.format;
9673                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9674                         params.allocationKind                           = allocationKind;
9675                         params.extensionUse                                     = extensionUse;
9676                         params.separateDepthStencilLayouts      = DE_FALSE;
9677
9678                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9679                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9680
9681                         CopyRegion      region;
9682                         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
9683                         {
9684                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
9685                                 const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
9686                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
9687                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
9688
9689                                 if (hasDepth)
9690                                 {
9691                                         const VkImageBlit                       imageBlit       =
9692                                         {
9693                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9694                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9695                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9696                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9697                                         };
9698                                         region.imageBlit        = imageBlit;
9699                                         params.regions.push_back(region);
9700                                 }
9701                                 if (hasStencil)
9702                                 {
9703                                         const VkImageBlit                       imageBlit       =
9704                                         {
9705                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9706                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9707                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9708                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9709                                         };
9710                                         region.imageBlit        = imageBlit;
9711                                         params.regions.push_back(region);
9712                                 }
9713                         }
9714                         for (int i = 0; i < defaultSize; i += defaultFourthSize)
9715                         {
9716                                 const VkOffset3D        srcOffset0      = {i, i, 0};
9717                                 const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
9718                                 const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
9719                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
9720
9721                                 if (hasDepth)
9722                                 {
9723                                         const VkImageBlit                       imageBlit       =
9724                                         {
9725                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9726                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9727                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9728                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9729                                         };
9730                                         region.imageBlit        = imageBlit;
9731                                         params.regions.push_back(region);
9732                                 }
9733                                 if (hasStencil)
9734                                 {
9735                                         const VkImageBlit                       imageBlit       =
9736                                         {
9737                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9738                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9739                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9740                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9741                                         };
9742                                         region.imageBlit        = imageBlit;
9743                                         params.regions.push_back(region);
9744                                 }
9745                                 if (hasDepth && hasStencil)
9746                                 {
9747                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultFourthSize, 0};
9748                                         const VkOffset3D                        dstDSOffset1    = {i + defaultFourthSize, defaultSize, 1};
9749                                         const VkImageBlit                       imageBlit       =
9750                                         {
9751                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
9752                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9753                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
9754                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
9755                                         };
9756                                         region.imageBlit        = imageBlit;
9757                                         params.regions.push_back(region);
9758                                 }
9759                         }
9760
9761                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9762                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
9763                                                                                         " to " + getFormatCaseName(params.dst.image.format);
9764                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
9765
9766                         if (hasDepth && hasStencil)
9767                         {
9768                                 params.separateDepthStencilLayouts      = DE_TRUE;
9769                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
9770                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9771                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
9772                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9773                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
9774                         }
9775                 }
9776
9777                 group->addChild(subGroup.release());
9778         }
9779
9780         // 1D tests
9781         {
9782                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
9783
9784                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9785                 {
9786                         TestParams      params;
9787                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
9788                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
9789                         params.src.image.extent                         = default1dExtent;
9790                         params.dst.image.extent                         = default1dExtent;
9791                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
9792                         params.dst.image.format                         = params.src.image.format;
9793                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9794                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9795                         params.allocationKind                           = allocationKind;
9796                         params.extensionUse                                     = extensionUse;
9797
9798                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9799                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9800
9801                         CopyRegion      region;
9802                         for (int i = 0; i < defaultSize; i += defaultSize / 2)
9803                         {
9804                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
9805                                 const VkOffset3D        srcOffset1      = {defaultSize, 1, 1};
9806                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
9807                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, 1, 1};
9808
9809                                 if (hasDepth)
9810                                 {
9811                                         const VkImageBlit                       imageBlit       =
9812                                         {
9813                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9814                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9815                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9816                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9817                                         };
9818                                         region.imageBlit        = imageBlit;
9819                                         params.regions.push_back(region);
9820                                 }
9821                                 if (hasStencil)
9822                                 {
9823                                         const VkImageBlit                       imageBlit       =
9824                                         {
9825                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9826                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9827                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9828                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9829                                         };
9830                                         region.imageBlit        = imageBlit;
9831                                         params.regions.push_back(region);
9832                                 }
9833                         }
9834
9835                         {
9836                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
9837                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, 1, 1};
9838                                 const VkOffset3D        dstOffset0      = {defaultFourthSize, 0, 0};
9839                                 const VkOffset3D        dstOffset1      = {2 * defaultFourthSize, 1, 1};
9840
9841                                 if (hasDepth)
9842                                 {
9843                                         const VkImageBlit                       imageBlit       =
9844                                         {
9845                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9846                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9847                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9848                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9849                                         };
9850                                         region.imageBlit        = imageBlit;
9851                                         params.regions.push_back(region);
9852                                 }
9853                                 if (hasStencil)
9854                                 {
9855                                         const VkImageBlit                       imageBlit       =
9856                                         {
9857                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9858                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9859                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9860                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9861                                         };
9862                                         region.imageBlit        = imageBlit;
9863                                         params.regions.push_back(region);
9864                                 }
9865                                 if (hasDepth && hasStencil)
9866                                 {
9867                                         const VkOffset3D                        dstDSOffset0    = {3 * defaultFourthSize, 0, 0};
9868                                         const VkOffset3D                        dstDSOffset1    = {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
9869                                         const VkImageBlit                       imageBlit       =
9870                                         {
9871                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
9872                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9873                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
9874                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
9875                                         };
9876                                         region.imageBlit        = imageBlit;
9877                                         params.regions.push_back(region);
9878                                 }
9879                         }
9880
9881                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9882                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
9883                                                                                         " to " + getFormatCaseName(params.dst.image.format);
9884                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
9885
9886                         if (hasDepth && hasStencil)
9887                         {
9888                                 params.separateDepthStencilLayouts      = DE_TRUE;
9889                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
9890                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9891                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
9892                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9893                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
9894                         }
9895                 }
9896
9897                 group->addChild(subGroup.release());
9898         }
9899
9900         // 3D tests. Note we use smaller dimensions here for performance reasons.
9901         {
9902                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
9903
9904                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9905                 {
9906                         TestParams      params;
9907                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
9908                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
9909                         params.src.image.extent                         = default3dExtent;
9910                         params.dst.image.extent                         = default3dExtent;
9911                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
9912                         params.dst.image.format                         = params.src.image.format;
9913                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9914                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9915                         params.allocationKind                           = allocationKind;
9916                         params.extensionUse                                     = extensionUse;
9917
9918                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9919                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9920
9921                         CopyRegion      region;
9922                         for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
9923                         {
9924                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
9925                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
9926                                 const VkOffset3D        dstOffset0      = {i, 0, i};
9927                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
9928
9929                                 if (hasDepth)
9930                                 {
9931                                         const VkImageBlit                       imageBlit       =
9932                                         {
9933                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9934                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9935                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9936                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9937                                         };
9938                                         region.imageBlit        = imageBlit;
9939                                         params.regions.push_back(region);
9940                                 }
9941                                 if (hasStencil)
9942                                 {
9943                                         const VkImageBlit                       imageBlit       =
9944                                         {
9945                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9946                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
9947                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9948                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
9949                                         };
9950                                         region.imageBlit        = imageBlit;
9951                                         params.regions.push_back(region);
9952                                 }
9953                         }
9954                         for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
9955                         {
9956                                 const VkOffset3D        srcOffset0      = {i, i, i};
9957                                 const VkOffset3D        srcOffset1      = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
9958                                 const VkOffset3D        dstOffset0      = {i, defaultFourthSize / 2, i};
9959                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
9960
9961                                 if (hasDepth)
9962                                 {
9963                                         const VkImageBlit                       imageBlit       =
9964                                         {
9965                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
9966                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9967                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
9968                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9969                                         };
9970                                         region.imageBlit        = imageBlit;
9971                                         params.regions.push_back(region);
9972                                 }
9973                                 if (hasStencil)
9974                                 {
9975                                         const VkImageBlit                       imageBlit       =
9976                                         {
9977                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
9978                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9979                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
9980                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
9981                                         };
9982                                         region.imageBlit        = imageBlit;
9983                                         params.regions.push_back(region);
9984                                 }
9985                                 if (hasDepth && hasStencil)
9986                                 {
9987                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultSixteenthSize, i};
9988                                         const VkOffset3D                        dstDSOffset1    = {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
9989                                         const VkImageBlit                       imageBlit       =
9990                                         {
9991                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
9992                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
9993                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
9994                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
9995                                         };
9996                                         region.imageBlit        = imageBlit;
9997                                         params.regions.push_back(region);
9998                                 }
9999                         }
10000
10001                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10002                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
10003                                                                                         " to " + getFormatCaseName(params.dst.image.format);
10004                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
10005
10006                         if (hasDepth && hasStencil)
10007                         {
10008                                 params.separateDepthStencilLayouts      = DE_TRUE;
10009                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
10010                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10011                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
10012                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
10013                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
10014                         }
10015                 }
10016
10017                 group->addChild(subGroup.release());
10018         }
10019 }
10020
10021 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10022 {
10023         tcu::TestContext& testCtx                               = group->getTestContext();
10024
10025         const VkImageLayout blitSrcLayouts[]    =
10026         {
10027                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10028                 VK_IMAGE_LAYOUT_GENERAL
10029         };
10030         const VkImageLayout blitDstLayouts[]    =
10031         {
10032                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10033                 VK_IMAGE_LAYOUT_GENERAL
10034         };
10035
10036         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10037         {
10038                 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
10039                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10040                 {
10041                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
10042
10043                         testParams.params.filter                        = VK_FILTER_NEAREST;
10044                         const std::string testName                      = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
10045                                                                                                   getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
10046                         const std::string description           = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
10047                                                                                                   " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
10048                         group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
10049
10050                         if (testParams.testFilters & FILTER_MASK_LINEAR)
10051                         {
10052                                 testParams.params.filter = VK_FILTER_LINEAR;
10053                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
10054                         }
10055
10056                         if (testParams.testFilters & FILTER_MASK_CUBIC)
10057                         {
10058                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
10059                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
10060                         }
10061                 }
10062         }
10063 }
10064
10065 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10066 {
10067         const struct
10068         {
10069                 const VkFormat* const   compatibleFormats;
10070                 const bool                              onlyNearest;
10071         }       colorImageFormatsToTestBlit[]                   =
10072         {
10073                 { compatibleFormatsUInts,       true    },
10074                 { compatibleFormatsSInts,       true    },
10075                 { compatibleFormatsFloats,      false   },
10076                 { compatibleFormatsSrgb,        false   },
10077         };
10078
10079         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
10080
10081         const int       layerCountsToTest[]                             =
10082         {
10083                 1,
10084                 6
10085         };
10086
10087         TestParams      params;
10088         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
10089         params.src.image.extent         = defaultExtent;
10090         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10091         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
10092         params.dst.image.extent         = defaultExtent;
10093         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10094         params.allocationKind           = allocationKind;
10095         params.extensionUse                     = extensionUse;
10096         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
10097         params.singleCommand            = DE_TRUE;
10098
10099         CopyRegion      region;
10100         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
10101         {
10102                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
10103                 destLayer.mipLevel = mipLevelNdx;
10104
10105                 const VkImageBlit                       imageBlit       =
10106                 {
10107                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10108                         {
10109                                 {0, 0, 0},
10110                                 {defaultSize, defaultSize, 1}
10111                         },                                      // VkOffset3D                                   srcOffsets[2];
10112
10113                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
10114                         {
10115                                 {0, 0, 0},
10116                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
10117                         }                                       // VkOffset3D                                   dstOffset[2];
10118                 };
10119                 region.imageBlit        = imageBlit;
10120                 params.regions.push_back(region);
10121         }
10122
10123         if (allocationKind == ALLOCATION_KIND_DEDICATED)
10124         {
10125                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
10126                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
10127                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
10128         }
10129
10130         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
10131         {
10132                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
10133                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
10134                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
10135
10136                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
10137
10138                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10139                 {
10140                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
10141                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10142
10143                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10144                         {
10145                                 params.src.image.format = compatibleFormats[srcFormatIndex];
10146                                 params.dst.image.format = compatibleFormats[srcFormatIndex];
10147
10148                                 if (!isSupportedByFramework(params.src.image.format))
10149                                         continue;
10150
10151                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
10152
10153                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10154
10155                                 BlitColorTestParams testParams;
10156                                 testParams.params                               = params;
10157                                 testParams.compatibleFormats    = compatibleFormats;
10158                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
10159
10160                                 testParams.params.src.image.extent.depth = layerCount;
10161                                 testParams.params.dst.image.extent.depth = layerCount;
10162
10163                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
10164                                 {
10165                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
10166                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
10167                                 }
10168
10169                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
10170                         }
10171                 }
10172                 group->addChild(layerCountGroup.release());
10173         }
10174 }
10175
10176 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10177 {
10178         const struct
10179         {
10180                 const VkFormat* const   compatibleFormats;
10181                 const bool                              onlyNearest;
10182         }       colorImageFormatsToTestBlit[]                   =
10183         {
10184                 { compatibleFormatsUInts,       true    },
10185                 { compatibleFormatsSInts,       true    },
10186                 { compatibleFormatsFloats,      false   },
10187                 { compatibleFormatsSrgb,        false   },
10188         };
10189
10190         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
10191
10192         const int       layerCountsToTest[]                             =
10193         {
10194                 1,
10195                 6
10196         };
10197
10198         TestParams      params;
10199         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
10200         params.src.image.extent         = defaultExtent;
10201         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10202         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
10203         params.dst.image.extent         = defaultExtent;
10204         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10205         params.allocationKind           = allocationKind;
10206         params.extensionUse                     = extensionUse;
10207         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
10208         params.singleCommand            = DE_FALSE;
10209
10210         CopyRegion      region;
10211         for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
10212         {
10213                 VkImageSubresourceLayers        srcLayer        = defaultSourceLayer;
10214                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
10215
10216                 srcLayer.mipLevel       = mipLevelNdx - 1u;
10217                 destLayer.mipLevel      = mipLevelNdx;
10218
10219                 const VkImageBlit                       imageBlit       =
10220                 {
10221                         srcLayer,                       // VkImageSubresourceLayers     srcSubresource;
10222                         {
10223                                 {0, 0, 0},
10224                                 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
10225                         },                                      // VkOffset3D                                   srcOffsets[2];
10226
10227                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
10228                         {
10229                                 {0, 0, 0},
10230                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
10231                         }                                       // VkOffset3D                                   dstOffset[2];
10232                 };
10233                 region.imageBlit        = imageBlit;
10234                 params.regions.push_back(region);
10235         }
10236
10237         if (allocationKind == ALLOCATION_KIND_DEDICATED)
10238         {
10239                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
10240                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
10241                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
10242         }
10243
10244         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
10245         {
10246                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
10247                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
10248                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
10249
10250                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
10251
10252                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10253                 {
10254                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
10255                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10256
10257                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10258                         {
10259                                 params.src.image.format                                         = compatibleFormats[srcFormatIndex];
10260                                 params.dst.image.format                                         = compatibleFormats[srcFormatIndex];
10261
10262                                 if (!isSupportedByFramework(params.src.image.format))
10263                                         continue;
10264
10265                                 const bool                      onlyNearestAndLinear    = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
10266
10267                                 const std::string       description                             = "Blit source format " + getFormatCaseName(params.src.image.format);
10268
10269                                 BlitColorTestParams     testParams;
10270                                 testParams.params                                                       = params;
10271                                 testParams.compatibleFormats                            = compatibleFormats;
10272                                 testParams.testFilters                                          = makeFilterMask(onlyNearest, onlyNearestAndLinear);
10273
10274                                 testParams.params.src.image.extent.depth        = layerCount;
10275                                 testParams.params.dst.image.extent.depth        = layerCount;
10276
10277                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
10278                                 {
10279                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
10280                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
10281                                 }
10282
10283                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
10284                         }
10285                 }
10286                 group->addChild(layerCountGroup.release());
10287         }
10288
10289         for (int multiLayer = 0; multiLayer < 2; multiLayer++)
10290         {
10291                 const int layerCount = multiLayer ? 6 : 1;
10292
10293                 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
10294                 {
10295                         if (layerCount != 1 || barrierCount != 1)
10296                         {
10297                                 const std::string                               barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
10298                                 const std::string                               barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
10299
10300                                 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
10301
10302                                 params.barrierCount = barrierCount;
10303
10304                                 // Only go through a few common formats
10305                                 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
10306                                 {
10307                                         params.src.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
10308                                         params.dst.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
10309
10310                                         if (!isSupportedByFramework(params.src.image.format))
10311                                                 continue;
10312
10313                                         const std::string description                           = "Blit source format " + getFormatCaseName(params.src.image.format);
10314
10315                                         BlitColorTestParams testParams;
10316                                         testParams.params                                                       = params;
10317                                         testParams.compatibleFormats                            = compatibleFormatsUInts;
10318                                         testParams.testFilters                                          = FILTER_MASK_NEAREST;
10319
10320                                         testParams.params.src.image.extent.depth        = layerCount;
10321                                         testParams.params.dst.image.extent.depth        = layerCount;
10322
10323                                         for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
10324                                         {
10325                                                 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
10326                                                 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
10327                                         }
10328
10329                                         addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
10330                                 }
10331                                 group->addChild(barrierCountGroup.release());
10332                         }
10333                 }
10334         }
10335 }
10336
10337 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10338 {
10339         addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
10340         addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
10341 }
10342
10343 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10344 {
10345         addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
10346         addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
10347         addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
10348 }
10349
10350 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10351 {
10352         addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
10353         addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
10354 }
10355
10356 const VkSampleCountFlagBits     samples[]               =
10357 {
10358         VK_SAMPLE_COUNT_2_BIT,
10359         VK_SAMPLE_COUNT_4_BIT,
10360         VK_SAMPLE_COUNT_8_BIT,
10361         VK_SAMPLE_COUNT_16_BIT,
10362         VK_SAMPLE_COUNT_32_BIT,
10363         VK_SAMPLE_COUNT_64_BIT
10364 };
10365 const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
10366
10367 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10368 {
10369         TestParams      params;
10370         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10371         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10372         params.src.image.extent                         = resolveExtent;
10373         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10374         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10375         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10376         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10377         params.dst.image.extent                         = resolveExtent;
10378         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10379         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10380         params.allocationKind                           = allocationKind;
10381         params.extensionUse                                     = extensionUse;
10382
10383         {
10384                 const VkImageSubresourceLayers  sourceLayer     =
10385                 {
10386                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
10387                         0u,                                                     // deUint32                             mipLevel;
10388                         0u,                                                     // deUint32                             baseArrayLayer;
10389                         1u                                                      // deUint32                             layerCount;
10390                 };
10391                 const VkImageResolve                    testResolve     =
10392                 {
10393                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
10394                         {0, 0, 0},              // VkOffset3D                           srcOffset;
10395                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
10396                         {0, 0, 0},              // VkOffset3D                           dstOffset;
10397                         resolveExtent,  // VkExtent3D                           extent;
10398                 };
10399
10400                 CopyRegion      imageResolve;
10401                 imageResolve.imageResolve       = testResolve;
10402                 params.regions.push_back(imageResolve);
10403         }
10404
10405         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10406         {
10407                 params.samples                                  = samples[samplesIndex];
10408                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10409                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
10410         }
10411 }
10412
10413 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10414 {
10415         TestParams      params;
10416         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10417         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10418         params.src.image.extent                         = resolveExtent;
10419         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10420         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10421         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10422         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10423         params.dst.image.extent                         = resolveExtent;
10424         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10425         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10426         params.allocationKind                           = allocationKind;
10427         params.extensionUse                                     = extensionUse;
10428
10429         {
10430                 const VkImageSubresourceLayers  sourceLayer     =
10431                 {
10432                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
10433                         0u,                                                     // deUint32                             mipLevel;
10434                         0u,                                                     // deUint32                             baseArrayLayer;
10435                         1u                                                      // deUint32                             layerCount;
10436                 };
10437                 const VkImageResolve                    testResolve     =
10438                 {
10439                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
10440                         {0, 0, 0},              // VkOffset3D                           srcOffset;
10441                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
10442                         {64u, 64u, 0},          // VkOffset3D                           dstOffset;
10443                         {128u, 128u, 1u},       // VkExtent3D                           extent;
10444                 };
10445
10446                 CopyRegion      imageResolve;
10447                 imageResolve.imageResolve = testResolve;
10448                 params.regions.push_back(imageResolve);
10449         }
10450
10451         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10452         {
10453                 params.samples                                  = samples[samplesIndex];
10454                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10455                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
10456         }
10457 }
10458
10459 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10460 {
10461         TestParams      params;
10462         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10463         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10464         params.src.image.extent                         = resolveExtent;
10465         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10466         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10467         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10468         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10469         params.dst.image.extent                         = resolveExtent;
10470         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10471         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10472         params.allocationKind                           = allocationKind;
10473         params.extensionUse                                     = extensionUse;
10474
10475         {
10476                 const VkImageSubresourceLayers  sourceLayer     =
10477                 {
10478                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
10479                         0u,                                                     // deUint32                             mipLevel;
10480                         0u,                                                     // deUint32                             baseArrayLayer;
10481                         1u                                                      // deUint32                             layerCount;
10482                 };
10483
10484                 for (int i = 0; i < 256; i += 64)
10485                 {
10486                         const VkImageResolve                    testResolve     =
10487                         {
10488                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
10489                                 {i, i, 0},              // VkOffset3D                           srcOffset;
10490                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
10491                                 {i, 0, 0},              // VkOffset3D                           dstOffset;
10492                                 {64u, 64u, 1u}, // VkExtent3D                           extent;
10493                         };
10494
10495                         CopyRegion      imageResolve;
10496                         imageResolve.imageResolve = testResolve;
10497                         params.regions.push_back(imageResolve);
10498                 }
10499         }
10500
10501         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10502         {
10503                 params.samples                                  = samples[samplesIndex];
10504                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10505                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
10506         }
10507 }
10508
10509 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10510 {
10511         TestParams      params;
10512         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10513         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10514         params.src.image.extent                         = defaultExtent;
10515         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10516         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10517         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10518         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10519         params.dst.image.extent                         = defaultExtent;
10520         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10521         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10522         params.allocationKind                           = allocationKind;
10523         params.extensionUse                                     = extensionUse;
10524
10525         {
10526                 const VkImageSubresourceLayers  sourceLayer     =
10527                 {
10528                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
10529                         0u,                                                     // deUint32                             mipLevel;
10530                         0u,                                                     // deUint32                             baseArrayLayer;
10531                         1u                                                      // deUint32                             layerCount;
10532                 };
10533
10534                 const VkImageResolve                    testResolve     =
10535                 {
10536                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
10537                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
10538                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
10539                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
10540                         defaultExtent,          // VkExtent3D                           extent;
10541                 };
10542
10543                 CopyRegion      imageResolve;
10544                 imageResolve.imageResolve       = testResolve;
10545                 params.regions.push_back(imageResolve);
10546         }
10547
10548         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10549         {
10550                 params.samples                                  = samples[samplesIndex];
10551                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10552                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
10553         }
10554 }
10555
10556 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10557 {
10558         TestParams      params;
10559         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10560         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10561         params.src.image.extent                         = defaultExtent;
10562         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10563         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10564         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10565         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10566         params.dst.image.extent                         = defaultExtent;
10567         params.dst.image.extent.depth           = 5u;
10568         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10569         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10570         params.allocationKind                           = allocationKind;
10571         params.extensionUse                                     = extensionUse;
10572
10573         for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
10574         {
10575                 const VkImageSubresourceLayers  sourceLayer     =
10576                 {
10577                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
10578                         0u,                                                             // deUint32                             mipLevel;
10579                         layerNdx,                                               // deUint32                             baseArrayLayer;
10580                         1u                                                              // deUint32                             layerCount;
10581                 };
10582
10583                 const VkImageResolve                    testResolve     =
10584                 {
10585                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
10586                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
10587                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
10588                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
10589                         defaultExtent,          // VkExtent3D                           extent;
10590                 };
10591
10592                 CopyRegion      imageResolve;
10593                 imageResolve.imageResolve       = testResolve;
10594                 params.regions.push_back(imageResolve);
10595         }
10596
10597         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10598         {
10599                 params.samples                                  = samples[samplesIndex];
10600                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10601                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
10602         }
10603 }
10604
10605 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10606 {
10607         TestParams      params;
10608         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10609         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10610         params.src.image.extent                         = defaultExtent;
10611         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10612         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10613         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10614         params.dst.image.extent                         = defaultExtent;
10615         params.dst.image.extent.depth           = 5u;
10616         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10617         params.allocationKind                           = allocationKind;
10618         params.extensionUse                                     = extensionUse;
10619
10620         const VkImageSubresourceLayers  sourceLayer     =
10621         {
10622                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
10623                 0u,                                                             // uint32_t                             mipLevel;
10624                 0,                                              // uint32_t                             baseArrayLayer;
10625                 params.dst.image.extent.depth                   // uint32_t                             layerCount;
10626         };
10627
10628         const VkImageResolve                    testResolve     =
10629         {
10630                 sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
10631                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
10632                 sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
10633                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
10634                 defaultExtent,          // VkExtent3D                           extent;
10635         };
10636
10637         CopyRegion      imageResolve;
10638         imageResolve.imageResolve       = testResolve;
10639         params.regions.push_back(imageResolve);
10640
10641         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10642         {
10643                 params.samples                                  = samples[samplesIndex];
10644                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
10645                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
10646         }
10647 }
10648
10649 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10650 {
10651         tcu::TestContext&       testCtx                 = group->getTestContext();
10652         TestParams                      params;
10653         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10654         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10655         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10656         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10657         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10658         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10659         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10660         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10661         params.allocationKind                           = allocationKind;
10662         params.extensionUse                                     = extensionUse;
10663
10664         {
10665                 const VkImageSubresourceLayers  sourceLayer     =
10666                 {
10667                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
10668                         0u,                                                     // deUint32                             mipLevel;
10669                         0u,                                                     // deUint32                             baseArrayLayer;
10670                         1u                                                      // deUint32                             layerCount;
10671                 };
10672                 const VkImageResolve                    testResolve     =
10673                 {
10674                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
10675                         {0, 0, 0},              // VkOffset3D                           srcOffset;
10676                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
10677                         {0, 0, 0},              // VkOffset3D                           dstOffset;
10678                         resolveExtent,  // VkExtent3D                           extent;
10679                 };
10680                 CopyRegion      imageResolve;
10681                 imageResolve.imageResolve       = testResolve;
10682                 params.regions.push_back(imageResolve);
10683         }
10684
10685         const VkExtent3D imageExtents[]         =
10686         {
10687                 { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
10688                 { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
10689                 { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
10690         };
10691
10692         for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
10693         {
10694                 const VkExtent3D&       srcImageSize    = imageExtents[srcImageExtentIndex];
10695                 params.src.image.extent                         = srcImageSize;
10696                 params.dst.image.extent                         = resolveExtent;
10697                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10698                 {
10699                         params.samples  = samples[samplesIndex];
10700                         std::ostringstream testName;
10701                         testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
10702                         std::ostringstream description;
10703                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
10704                                                 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
10705                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
10706                 }
10707         }
10708         for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
10709         {
10710                 const VkExtent3D&       dstImageSize    = imageExtents[dstImageExtentIndex];
10711                 params.src.image.extent                         = resolveExtent;
10712                 params.dst.image.extent                         = dstImageSize;
10713                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
10714                 {
10715                         params.samples  = samples[samplesIndex];
10716                         std::ostringstream testName;
10717                         testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
10718                         std::ostringstream description;
10719                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
10720                                                 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
10721                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
10722                 }
10723         }
10724 }
10725
10726 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
10727 {
10728         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset", "Copy from buffer to buffer using different offsets in the source and destination buffers"));
10729
10730         for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
10731         for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
10732         {
10733                 BufferOffsetParams params{srcOffset, dstOffset};
10734                 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
10735         }
10736
10737         group->addChild(subGroup.release());
10738 }
10739
10740 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10741 {
10742         addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
10743         addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
10744         addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
10745         addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
10746         addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
10747         addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
10748         addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
10749 }
10750
10751 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10752 {
10753         addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
10754         addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
10755         addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
10756         addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
10757         addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
10758         addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
10759         addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
10760 }
10761
10762 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
10763 {
10764         addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
10765         addBufferCopyOffsetTests(group);
10766 }
10767
10768
10769 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
10770 {
10771         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
10772 }
10773
10774 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
10775 {
10776         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
10777 }
10778
10779 } // anonymous
10780
10781 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
10782 {
10783         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
10784
10785         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
10786         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",       "Copies And Blitting Tests For Dedicated Memory Allocation",    addDedicatedAllocationCopiesAndBlittingTests));
10787         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
10788
10789         return copiesAndBlittingTests.release();
10790 }
10791
10792 } // api
10793 } // vkt