Merge pull request #276 from Ella-0/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015-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 "tcuAstcUtil.hpp"
33 #include "tcuTexture.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuVectorType.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuTexLookupVerifier.hpp"
39
40 #include "vkImageUtil.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkPrograms.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vktTestCase.hpp"
46 #include "vktTestCaseUtil.hpp"
47 #include "vktTestGroupUtil.hpp"
48 #include "vkTypeUtil.hpp"
49 #include "vkCmdUtil.hpp"
50 #include "vkObjUtil.hpp"
51 #include "vkBuilderUtil.hpp"
52 #include "vkBufferWithMemory.hpp"
53 #include "vkBarrierUtil.hpp"
54
55 #include "pipeline/vktPipelineImageUtil.hpp"            // required for compressed image blit
56
57 #include <set>
58 #include <array>
59 #include <algorithm>
60 #include <iterator>
61 #include <sstream>
62
63 namespace vkt
64 {
65
66 namespace api
67 {
68
69 namespace
70 {
71
72 enum FillMode
73 {
74         FILL_MODE_GRADIENT = 0,
75         FILL_MODE_WHITE,
76         FILL_MODE_BLACK,
77         FILL_MODE_RED,
78         FILL_MODE_MULTISAMPLE,
79         FILL_MODE_BLUE_RED_X,
80         FILL_MODE_BLUE_RED_Y,
81         FILL_MODE_BLUE_RED_Z,
82
83         FILL_MODE_LAST
84 };
85
86 enum MirrorModeBits
87 {
88         MIRROR_MODE_X           = (1<<0),
89         MIRROR_MODE_Y           = (1<<1),
90         MIRROR_MODE_Z           = (1<<2),
91         MIRROR_MODE_LAST        = (1<<3),
92 };
93
94 using MirrorMode = deUint32;
95
96 enum AllocationKind
97 {
98         ALLOCATION_KIND_SUBALLOCATED,
99         ALLOCATION_KIND_DEDICATED,
100 };
101
102 enum ExtensionUse
103 {
104         EXTENSION_USE_NONE,
105         EXTENSION_USE_COPY_COMMANDS2,
106 };
107
108 template <typename Type>
109 class BinaryCompare
110 {
111 public:
112         bool operator() (const Type& a, const Type& b) const
113         {
114                 return deMemCmp(&a, &b, sizeof(Type)) < 0;
115         }
116 };
117
118 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >    FormatSet;
119
120 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
121 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
122
123 using namespace vk;
124
125 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
126 {
127         const VkImageCopy2KHR   imageCopy2 =
128         {
129                 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,             // VkStructureType                              sType;
130                 DE_NULL,                                                                // const void*                                  pNext;
131                 imageCopy.srcSubresource,                               // VkImageSubresourceLayers             srcSubresource;
132                 imageCopy.srcOffset,                                    // VkOffset3D                                   srcOffset;
133                 imageCopy.dstSubresource,                               // VkImageSubresourceLayers             dstSubresource;
134                 imageCopy.dstOffset,                                    // VkOffset3D                                   dstOffset;
135                 imageCopy.extent                                                // VkExtent3D                                   extent;
136         };
137         return imageCopy2;
138 }
139 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
140 {
141         const VkBufferCopy2KHR  bufferCopy2 =
142         {
143                 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,    // VkStructureType                              sType;
144                 DE_NULL,                                                                // const void*                                  pNext;
145                 bufferCopy.srcOffset,                                   // VkDeviceSize                                 srcOffset;
146                 bufferCopy.dstOffset,                                   // VkDeviceSize                                 dstOffset;
147                 bufferCopy.size,                                                // VkDeviceSize                                 size;
148         };
149         return bufferCopy2;
150 }
151
152 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
153 {
154         const VkBufferImageCopy2KHR     bufferImageCopy2 =
155         {
156                 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,      // VkStructureType                              sType;
157                 DE_NULL,                                                                        // const void*                                  pNext;
158                 bufferImageCopy.bufferOffset,                           // VkDeviceSize                                 bufferOffset;
159                 bufferImageCopy.bufferRowLength,                        // uint32_t                                             bufferRowLength;
160                 bufferImageCopy.bufferImageHeight,                      // uint32_t                                             bufferImageHeight;
161                 bufferImageCopy.imageSubresource,                       // VkImageSubresourceLayers             imageSubresource;
162                 bufferImageCopy.imageOffset,                            // VkOffset3D                                   imageOffset;
163                 bufferImageCopy.imageExtent                                     // VkExtent3D                                   imageExtent;
164         };
165         return bufferImageCopy2;
166 }
167
168 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
169 {
170         const VkImageBlit2KHR   imageBlit2 =
171         {
172                 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,                     // VkStructureType                              sType;
173                 DE_NULL,                                                                        // const void*                                  pNext;
174                 imageBlit.srcSubresource,                                       // VkImageSubresourceLayers             srcSubresource;
175                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
176                         {
177                                 imageBlit.srcOffsets[0].x,                              // VkOffset3D                   srcOffsets[0].x;
178                                 imageBlit.srcOffsets[0].y,                              // VkOffset3D                   srcOffsets[0].y;
179                                 imageBlit.srcOffsets[0].z                               // VkOffset3D                   srcOffsets[0].z;
180                         },
181                         {
182                                 imageBlit.srcOffsets[1].x,                              // VkOffset3D                   srcOffsets[1].x;
183                                 imageBlit.srcOffsets[1].y,                              // VkOffset3D                   srcOffsets[1].y;
184                                 imageBlit.srcOffsets[1].z                               // VkOffset3D                   srcOffsets[1].z;
185                         }
186                 },
187                 imageBlit.dstSubresource,                                       // VkImageSubresourceLayers             dstSubresource;
188                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
189                         {
190                                 imageBlit.dstOffsets[0].x,                              // VkOffset3D                   dstOffsets[0].x;
191                                 imageBlit.dstOffsets[0].y,                              // VkOffset3D                   dstOffsets[0].y;
192                                 imageBlit.dstOffsets[0].z                               // VkOffset3D                   dstOffsets[0].z;
193                         },
194                         {
195                                 imageBlit.dstOffsets[1].x,                              // VkOffset3D                   dstOffsets[1].x;
196                                 imageBlit.dstOffsets[1].y,                              // VkOffset3D                   dstOffsets[1].y;
197                                 imageBlit.dstOffsets[1].z                               // VkOffset3D                   dstOffsets[1].z;
198                         }
199                 }
200         };
201         return imageBlit2;
202 }
203
204 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
205 {
206         const VkImageResolve2KHR        imageResolve2 =
207         {
208                 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,          // VkStructureType                              sType;
209                 DE_NULL,                                                                        // const void*                                  pNext;
210                 imageResolve.srcSubresource,                            // VkImageSubresourceLayers             srcSubresource;
211                 imageResolve.srcOffset,                                         // VkOffset3D                                   srcOffset;
212                 imageResolve.dstSubresource,                            // VkImageSubresourceLayers             dstSubresource;
213                 imageResolve.dstOffset,                                         // VkOffset3D                                   dstOffset;
214                 imageResolve.extent                                                     // VkExtent3D                                   extent;
215         };
216         return imageResolve2;
217 }
218
219 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
220 {
221         VkImageAspectFlags      aspectFlag      = 0;
222         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
223         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
224
225         if (!aspectFlag)
226                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
227
228         return aspectFlag;
229 }
230
231 VkImageAspectFlags getAspectFlags (VkFormat format)
232 {
233         if (isCompressedFormat(format))
234                 return VK_IMAGE_ASPECT_COLOR_BIT;
235         else
236                 return getAspectFlags(mapVkFormat(format));
237 }
238
239 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
240 {
241         if (isCompressedFormat(format))
242                 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
243         else
244                 return mapVkFormat(format);
245 }
246
247 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
248 // except that it supports some formats that are not mappable to VkFormat.
249 // When we are checking combined depth and stencil formats, each aspect is
250 // checked separately, and in some cases we construct PBA with a format that
251 // is not mappable to VkFormat.
252 bool isFloatFormat (tcu::TextureFormat format)
253 {
254         return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
255 }
256
257 union CopyRegion
258 {
259         VkBufferCopy                    bufferCopy;
260         VkImageCopy                             imageCopy;
261         VkBufferImageCopy               bufferImageCopy;
262         VkImageBlit                             imageBlit;
263         VkImageResolve                  imageResolve;
264 };
265
266 struct ImageParms
267 {
268         VkImageType                     imageType;
269         VkFormat                        format;
270         VkExtent3D                      extent;
271         VkImageTiling           tiling;
272         VkImageLayout           operationLayout;
273         VkImageCreateFlags      createFlags;
274         FillMode                        fillMode;
275 };
276
277 struct TestParams
278 {
279         union Data
280         {
281                 struct Buffer
282                 {
283                         VkDeviceSize    size;
284                 } buffer;
285
286                 ImageParms      image;
287         } src, dst;
288
289         std::vector<CopyRegion> regions;
290
291         union
292         {
293                 VkFilter                                filter;
294                 VkSampleCountFlagBits   samples;
295         };
296
297         AllocationKind  allocationKind;
298         ExtensionUse    extensionUse;
299         deUint32                mipLevels;
300         deBool                  singleCommand;
301         deUint32                barrierCount;
302         deBool                  separateDepthStencilLayouts;
303         deBool                  clearDestination;
304
305         TestParams (void)
306         {
307                 allocationKind                          = ALLOCATION_KIND_DEDICATED;
308                 extensionUse                            = EXTENSION_USE_NONE;
309                 mipLevels                                       = 1u;
310                 singleCommand                           = DE_TRUE;
311                 barrierCount                            = 1u;
312                 separateDepthStencilLayouts     = DE_FALSE;
313                 src.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
314                 dst.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
315                 src.image.fillMode                      = FILL_MODE_GRADIENT;
316                 dst.image.fillMode                      = FILL_MODE_WHITE;
317                 clearDestination                        = DE_FALSE;
318                 samples                                         = VK_SAMPLE_COUNT_1_BIT;
319         }
320 };
321
322 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&        vki,
323                                                                                 const DeviceInterface&          vkd,
324                                                                                 const VkPhysicalDevice&         physDevice,
325                                                                                 const VkDevice                          device,
326                                                                                 const VkBuffer&                         buffer,
327                                                                                 const MemoryRequirement         requirement,
328                                                                                 Allocator&                                      allocator,
329                                                                                 AllocationKind                          allocationKind)
330 {
331         switch (allocationKind)
332         {
333                 case ALLOCATION_KIND_SUBALLOCATED:
334                 {
335                         const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
336
337                         return allocator.allocate(memoryRequirements, requirement);
338                 }
339
340                 case ALLOCATION_KIND_DEDICATED:
341                 {
342                         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
343                 }
344
345                 default:
346                 {
347                         TCU_THROW(InternalError, "Invalid allocation kind");
348                 }
349         }
350 }
351
352 de::MovePtr<Allocation> allocateImage (const InstanceInterface&         vki,
353                                                                            const DeviceInterface&               vkd,
354                                                                            const VkPhysicalDevice&              physDevice,
355                                                                            const VkDevice                               device,
356                                                                            const VkImage&                               image,
357                                                                            const MemoryRequirement              requirement,
358                                                                            Allocator&                                   allocator,
359                                                                            AllocationKind                               allocationKind)
360 {
361         switch (allocationKind)
362         {
363                 case ALLOCATION_KIND_SUBALLOCATED:
364                 {
365                         const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
366
367                         return allocator.allocate(memoryRequirements, requirement);
368                 }
369
370                 case ALLOCATION_KIND_DEDICATED:
371                 {
372                         return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
373                 }
374
375                 default:
376                 {
377                         TCU_THROW(InternalError, "Invalid allocation kind");
378                 }
379         }
380 }
381
382
383 inline deUint32 getArraySize(const ImageParms& parms)
384 {
385         return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
386 }
387
388 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
389 {
390         if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
391                 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
392         else
393                 return parms.createFlags;
394 }
395
396 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
397 {
398         const bool                      isCompressed    = isCompressedFormat(parms.format);
399         const deUint32          blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
400         const deUint32          blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
401
402         if (isCompressed && mipLevel != 0u)
403                 DE_FATAL("Not implemented");
404
405         const VkExtent3D        extent                  =
406         {
407                 (parms.extent.width >> mipLevel) * blockWidth,
408                 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
409                 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
410         };
411         return extent;
412 }
413
414 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
415 {
416         tcu::TextureFormat format;
417         switch (combinedFormat.type)
418         {
419                 case tcu::TextureFormat::UNORM_INT16:
420                 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
421                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
422                         break;
423                 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
424                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
425                         break;
426                 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
427                 case tcu::TextureFormat::FLOAT:
428                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
429                         break;
430                 default:
431                         DE_ASSERT(false);
432                         break;
433         }
434         return format;
435 }
436
437 class CopiesAndBlittingTestInstance : public vkt::TestInstance
438 {
439 public:
440                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
441                                                                                                                                                          TestParams     testParams);
442         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
443
444 protected:
445         const TestParams                                        m_params;
446
447         Move<VkCommandPool>                                     m_cmdPool;
448         Move<VkCommandBuffer>                           m_cmdBuffer;
449         Move<VkFence>                                           m_fence;
450         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
451         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
452         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel[16];
453
454         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
455
456         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
457         virtual void                                            generateExpectedResult                          (void);
458         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
459         void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
460         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
461         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
462         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
463                                                                                 {
464                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
465                                                                                 }
466
467         de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
468                                                                                                                                                          const ImageParms&                      imageParms,
469                                                                                                                                                          const deUint32                         mipLevel = 0u);
470
471 private:
472         void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
473                                                                                                                                                          const VkImage&                                         dst,
474                                                                                                                                                          const ImageParms&                                      parms,
475                                                                                                                                                          const deUint32                                         mipLevels = 1u);
476         void                                                            readImageAspect                                         (vk::VkImage                                            src,
477                                                                                                                                                          const tcu::PixelBufferAccess&          dst,
478                                                                                                                                                          const ImageParms&                                      parms,
479                                                                                                                                                          const deUint32                                         mipLevel = 0u);
480 };
481
482 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
483         : vkt::TestInstance     (context)
484         , m_params                      (testParams)
485 {
486         const DeviceInterface&          vk                                      = context.getDeviceInterface();
487         const VkDevice                          vkDevice                        = context.getDevice();
488         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
489
490         // Create command pool
491         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
492
493         // Create command buffer
494         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
495
496         // Create fence
497         m_fence = createFence(vk, vkDevice);
498 }
499
500 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
501 {
502         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(buffer.getFormat().type);
503         tcu::Vec4                                               maxValue                (1.0f);
504
505         if (buffer.getFormat().order == tcu::TextureFormat::S)
506         {
507                 // Stencil-only is stored in the first component. Stencil is always 8 bits.
508                 maxValue.x() = 1 << 8;
509         }
510         else if (buffer.getFormat().order == tcu::TextureFormat::DS)
511         {
512                 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
513                 maxValue.w() = 1 << 8;
514         }
515         else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
516         {
517                 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
518                 const tcu::IVec4        bits    = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
519                 const int                       signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
520
521                 for (int i = 0; i < 4; ++i)
522                 {
523                         if (bits[i] != 0)
524                                 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
525                 }
526         }
527
528         if (mode == FILL_MODE_GRADIENT)
529         {
530                 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
531                 return;
532         }
533
534         const tcu::Vec4         redColor        (maxValue.x(),  0.0,                    0.0,                    maxValue.w());
535         const tcu::Vec4         greenColor      (0.0,                   maxValue.y(),   0.0,                    maxValue.w());
536         const tcu::Vec4         blueColor       (0.0,                   0.0,                    maxValue.z(),   maxValue.w());
537         const tcu::Vec4         whiteColor      (maxValue.x(),  maxValue.y(),   maxValue.z(),   maxValue.w());
538         const tcu::Vec4         blackColor      (0.0f,                  0.0f,                   0.0f,                   0.0f);
539
540         for (int z = 0; z < depth;  ++z)
541         for (int y = 0; y < height; ++y)
542         for (int x = 0; x < width;  ++x)
543         {
544                 switch (mode)
545                 {
546                         case FILL_MODE_WHITE:
547                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
548                                 {
549                                         buffer.setPixDepth(1.0f, x, y, z);
550                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
551                                                 buffer.setPixStencil(255, x, y, z);
552                                 }
553                                 else
554                                         buffer.setPixel(whiteColor, x, y, z);
555                                 break;
556
557                         case FILL_MODE_BLACK:
558                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
559                                 {
560                                         buffer.setPixDepth(0.0f, x, y, z);
561                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
562                                                 buffer.setPixStencil(0, x, y, z);
563                                 }
564                                 else
565                                         buffer.setPixel(blackColor, x, y, z);
566                                 break;
567
568                         case FILL_MODE_RED:
569                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
570                                 {
571                                         buffer.setPixDepth(redColor[0], x, y, z);
572                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
573                                                 buffer.setPixStencil((int)redColor[3], x, y, z);
574                                 }
575                                 else
576                                         buffer.setPixel(redColor, x, y, z);
577                                 break;
578
579                         case FILL_MODE_BLUE_RED_X:
580                         case FILL_MODE_BLUE_RED_Y:
581                         case FILL_MODE_BLUE_RED_Z:
582                                 bool useBlue;
583                                 switch (mode)
584                                 {
585                                         case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
586                                         case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
587                                         case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
588                                         default: DE_ASSERT(false); break;
589                                 }
590                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
591                                 {
592                                         buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
593                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
594                                                 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
595                                 }
596                                 else
597                                         buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
598                                 break;
599
600                         case FILL_MODE_MULTISAMPLE:
601                         {
602                                 float xScaled = static_cast<float>(x) / static_cast<float>(width);
603                                 float yScaled = static_cast<float>(y) / static_cast<float>(height);
604                                 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
605                                 break;
606                         }
607
608                         default:
609                                 break;
610                 }
611         }
612 }
613
614 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
615 {
616         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
617         const VkDevice                          vkDevice        = m_context.getDevice();
618         const deUint32                          bufferSize      = calculateSize(bufferAccess);
619
620         // Write buffer data
621         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
622         flushAlloc(vk, vkDevice, bufferAlloc);
623 }
624
625 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
626 {
627         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
628         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
629         const VkPhysicalDevice                  vkPhysDevice            = m_context.getPhysicalDevice();
630         const VkDevice                                  vkDevice                        = m_context.getDevice();
631         const VkQueue                                   queue                           = m_context.getUniversalQueue();
632         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
633         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
634         Move<VkBuffer>                                  buffer;
635         const deUint32                                  bufferSize                      = calculateSize(imageAccess);
636         de::MovePtr<Allocation>                 bufferAlloc;
637         const deUint32                                  arraySize                       = getArraySize(parms);
638         const VkExtent3D                                imageExtent                     = getExtent3D(parms);
639         std::vector <VkBufferImageCopy> copyRegions;
640
641         // Create source buffer
642         {
643                 const VkBufferCreateInfo        bufferParams            =
644                 {
645                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
646                         DE_NULL,                                                                        // const void*                  pNext;
647                         0u,                                                                                     // VkBufferCreateFlags  flags;
648                         bufferSize,                                                                     // VkDeviceSize                 size;
649                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
650                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
651                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
652                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
653                 };
654
655                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
656                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
657                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
658         }
659
660         // Barriers for copying buffer to image
661         const VkBufferMemoryBarrier             preBufferBarrier        =
662         {
663                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
664                 DE_NULL,                                                                                // const void*          pNext;
665                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
666                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
667                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
668                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
669                 *buffer,                                                                                // VkBuffer                     buffer;
670                 0u,                                                                                             // VkDeviceSize         offset;
671                 bufferSize                                                                              // VkDeviceSize         size;
672         };
673
674         const VkImageAspectFlags                formatAspect            = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
675         const bool                                              skipPreImageBarrier     = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
676                                                                                                                   getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
677
678         const VkImageMemoryBarrier              preImageBarrier         =
679         {
680                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
681                 DE_NULL,                                                                                // const void*                          pNext;
682                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
683                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
684                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
685                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
686                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
687                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
688                 image,                                                                                  // VkImage                                      image;
689                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
690                         formatAspect,   // VkImageAspectFlags   aspect;
691                         0u,                             // deUint32                             baseMipLevel;
692                         mipLevels,              // deUint32                             mipLevels;
693                         0u,                             // deUint32                             baseArraySlice;
694                         arraySize,              // deUint32                             arraySize;
695                 }
696         };
697
698         const VkImageMemoryBarrier              postImageBarrier        =
699         {
700                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
701                 DE_NULL,                                                                                // const void*                          pNext;
702                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
703                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
704                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
705                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
706                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
707                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
708                 image,                                                                                  // VkImage                                      image;
709                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
710                         formatAspect,                           // VkImageAspectFlags   aspect;
711                         0u,                                                     // deUint32                             baseMipLevel;
712                         mipLevels,                                      // deUint32                             mipLevels;
713                         0u,                                                     // deUint32                             baseArraySlice;
714                         arraySize,                                      // deUint32                             arraySize;
715                 }
716         };
717
718         for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
719         {
720                 const VkExtent3D                copyExtent      =
721                 {
722                         imageExtent.width       >> mipLevelNdx,
723                         imageExtent.height      >> mipLevelNdx,
724                         imageExtent.depth
725                 };
726
727                 const bool              isCompressed    = isCompressedFormat(parms.format);
728                 const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
729                 const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
730                 deUint32 rowLength              = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
731                 deUint32 imageHeight    = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
732
733                 const VkBufferImageCopy copyRegion      =
734                 {
735                         0u,                                                                                             // VkDeviceSize                         bufferOffset;
736                         rowLength,                                                                              // deUint32                                     bufferRowLength;
737                         imageHeight,                                                                    // deUint32                                     bufferImageHeight;
738                         {
739                                 getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
740                                 mipLevelNdx,                                                                    // deUint32                             mipLevel;
741                                 0u,                                                                                             // deUint32                             baseArrayLayer;
742                                 arraySize,                                                                              // deUint32                             layerCount;
743                         },                                                                                              // VkImageSubresourceLayers     imageSubresource;
744                         { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
745                         copyExtent                                                                              // VkExtent3D                           imageExtent;
746                 };
747
748                 copyRegions.push_back(copyRegion);
749         }
750
751         // Write buffer data
752         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
753         flushAlloc(vk, vkDevice, *bufferAlloc);
754
755         // Copy buffer to image
756         beginCommandBuffer(vk, *m_cmdBuffer);
757         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
758                                                   1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
759         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
760         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);
761         endCommandBuffer(vk, *m_cmdBuffer);
762
763         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
764 }
765
766 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
767 {
768         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
769         {
770                 if (tcu::hasDepthComponent(src.getFormat().order))
771                 {
772                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
773                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
774                         uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
775                 }
776
777                 if (tcu::hasStencilComponent(src.getFormat().order))
778                 {
779                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
780                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
781                         uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
782                 }
783         }
784         else
785                 uploadImageAspect(src, dst, parms, mipLevels);
786 }
787
788 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
789 {
790         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel[0]->getAccess();
791
792         if (isFloatFormat(result.getFormat()))
793         {
794                 const tcu::Vec4 threshold (0.0f);
795                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
796                         return tcu::TestStatus::fail("CopiesAndBlitting test");
797         }
798         else
799         {
800                 const tcu::UVec4 threshold (0u);
801                 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
802                 {
803                         if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
804                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
805                 }
806                 else
807                 {
808                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
809                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
810                 }
811         }
812
813         return tcu::TestStatus::pass("CopiesAndBlitting test");
814 }
815
816 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
817 {
818         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
819         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
820
821         m_expectedTextureLevel[0]       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
822         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
823
824         for (deUint32 i = 0; i < m_params.regions.size(); i++)
825                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
826 }
827
828 class CopiesAndBlittingTestCase : public vkt::TestCase
829 {
830 public:
831                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
832                                                                                                                  const std::string&                     name,
833                                                                                                                  const std::string&                     description)
834                                                                 : vkt::TestCase (testCtx, name, description)
835                                                         {}
836
837         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
838 };
839
840 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                        image,
841                                                                                                          const tcu::PixelBufferAccess&  dst,
842                                                                                                          const ImageParms&                              imageParms,
843                                                                                                          const deUint32                                 mipLevel)
844 {
845         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
846         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
847         const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
848         const VkDevice                          device                          = m_context.getDevice();
849         const VkQueue                           queue                           = m_context.getUniversalQueue();
850         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
851
852         Move<VkBuffer>                          buffer;
853         de::MovePtr<Allocation>         bufferAlloc;
854         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
855         const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
856         const VkExtent3D                        imageExtent                     = getExtent3D(imageParms, mipLevel);
857
858         // Create destination buffer
859         {
860                 const VkBufferCreateInfo                        bufferParams                    =
861                 {
862                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
863                         DE_NULL,                                                                        // const void*                  pNext;
864                         0u,                                                                                     // VkBufferCreateFlags  flags;
865                         pixelDataSize,                                                          // VkDeviceSize                 size;
866                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
867                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
868                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
869                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
870                 };
871
872                 buffer          = createBuffer(vk, device, &bufferParams);
873                 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
874                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
875
876                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
877                 flushAlloc(vk, device, *bufferAlloc);
878         }
879
880         // Barriers for copying image to buffer
881         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(imageParms.format);
882         const VkImageMemoryBarrier                              imageBarrier                    =
883         {
884                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
885                 DE_NULL,                                                                        // const void*                          pNext;
886                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
887                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
888                 imageParms.operationLayout,                                     // VkImageLayout                        oldLayout;
889                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
890                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
891                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
892                 image,                                                                          // VkImage                                      image;
893                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
894                         formatAspect,                   // VkImageAspectFlags   aspectMask;
895                         mipLevel,                               // deUint32                             baseMipLevel;
896                         1u,                                             // deUint32                             mipLevels;
897                         0u,                                             // deUint32                             baseArraySlice;
898                         getArraySize(imageParms)// deUint32                             arraySize;
899                 }
900         };
901
902         const VkBufferMemoryBarrier                             bufferBarrier                   =
903         {
904                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
905                 DE_NULL,                                                                        // const void*          pNext;
906                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
907                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
908                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
909                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
910                 *buffer,                                                                        // VkBuffer                     buffer;
911                 0u,                                                                                     // VkDeviceSize         offset;
912                 pixelDataSize                                                           // VkDeviceSize         size;
913         };
914
915         const VkImageMemoryBarrier                              postImageBarrier                =
916         {
917                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
918                 DE_NULL,                                                                        // const void*                          pNext;
919                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
920                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
921                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        oldLayout;
922                 imageParms.operationLayout,                                     // VkImageLayout                        newLayout;
923                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
924                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
925                 image,                                                                          // VkImage                                      image;
926                 {
927                         formatAspect,                                                           // VkImageAspectFlags   aspectMask;
928                         mipLevel,                                                                       // deUint32                             baseMipLevel;
929                         1u,                                                                                     // deUint32                             mipLevels;
930                         0u,                                                                                     // deUint32                             baseArraySlice;
931                         getArraySize(imageParms)                                        // deUint32                             arraySize;
932                 }                                                                                       // VkImageSubresourceRange      subresourceRange;
933         };
934
935         // Copy image to buffer
936         const bool              isCompressed    = isCompressedFormat(imageParms.format);
937         const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
938         const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
939         deUint32 rowLength              = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
940         deUint32 imageHeight    = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
941
942         // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
943         const VkImageAspectFlags        aspect                  = isCompressedFormat(m_params.dst.image.format) ?
944                                                                                                         static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
945         const VkBufferImageCopy         copyRegion              =
946         {
947                 0u,                                                             // VkDeviceSize                         bufferOffset;
948                 rowLength,                                              // deUint32                                     bufferRowLength;
949                 imageHeight,                                    // deUint32                                     bufferImageHeight;
950                 {
951                         aspect,                                                 // VkImageAspectFlags           aspect;
952                         mipLevel,                                               // deUint32                                     mipLevel;
953                         0u,                                                             // deUint32                                     baseArrayLayer;
954                         getArraySize(imageParms),               // deUint32                                     layerCount;
955                 },                                                              // VkImageSubresourceLayers     imageSubresource;
956                 { 0, 0, 0 },                                    // VkOffset3D                           imageOffset;
957                 imageExtent                                             // VkExtent3D                           imageExtent;
958         };
959
960         beginCommandBuffer(vk, *m_cmdBuffer);
961         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);
962         vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
963         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);
964         endCommandBuffer(vk, *m_cmdBuffer);
965
966         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
967
968         // Read buffer data
969         invalidateAlloc(vk, device, *bufferAlloc);
970         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
971 }
972
973 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage            image,
974                                                                                                                                                  const ImageParms&      parms,
975                                                                                                                                                  const deUint32         mipLevel)
976 {
977         const tcu::TextureFormat                imageFormat     = getSizeCompatibleTcuTextureFormat(parms.format);
978         de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
979
980         if (tcu::isCombinedDepthStencilType(imageFormat.type))
981         {
982                 if (tcu::hasDepthComponent(imageFormat.order))
983                 {
984                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
985                         readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
986                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
987                 }
988
989                 if (tcu::hasStencilComponent(imageFormat.order))
990                 {
991                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
992                         readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
993                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
994                 }
995         }
996         else
997                 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
998
999         return resultLevel;
1000 }
1001
1002 // Copy from image to image.
1003
1004 class CopyImageToImage : public CopiesAndBlittingTestInstance
1005 {
1006 public:
1007                                                                                 CopyImageToImage                        (Context&       context,
1008                                                                                                                                          TestParams params);
1009         virtual tcu::TestStatus                         iterate                                         (void);
1010
1011 protected:
1012         virtual tcu::TestStatus                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1013
1014 private:
1015         Move<VkImage>                                           m_source;
1016         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1017         Move<VkImage>                                           m_destination;
1018         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1019
1020         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1021 };
1022
1023 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1024         : CopiesAndBlittingTestInstance(context, params)
1025 {
1026         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1027         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1028         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1029         const VkDevice                          vkDevice                        = context.getDevice();
1030         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1031         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1032
1033         // Create source image
1034         {
1035                 const VkImageCreateInfo sourceImageParams               =
1036                 {
1037                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1038                         DE_NULL,                                                                // const void*                  pNext;
1039                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1040                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1041                         m_params.src.image.format,                              // VkFormat                             format;
1042                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1043                         1u,                                                                             // deUint32                             mipLevels;
1044                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1045                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1046                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1047                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1048                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1049                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1050                         1u,                                                                             // deUint32                             queueFamilyCount;
1051                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1052                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1053                 };
1054
1055                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
1056                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1057                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1058         }
1059
1060         // Create destination image
1061         {
1062                 const VkImageCreateInfo destinationImageParams  =
1063                 {
1064                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1065                         DE_NULL,                                                                // const void*                  pNext;
1066                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1067                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1068                         m_params.dst.image.format,                              // VkFormat                             format;
1069                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1070                         1u,                                                                             // deUint32                             mipLevels;
1071                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1072                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1073                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1074                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1075                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1076                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1077                         1u,                                                                             // deUint32                             queueFamilyCount;
1078                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1079                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1080                 };
1081
1082                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1083                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1084                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1085         }
1086 }
1087
1088 tcu::TestStatus CopyImageToImage::iterate (void)
1089 {
1090         const bool                                      srcCompressed           = isCompressedFormat(m_params.src.image.format);
1091         const bool                                      dstCompressed           = isCompressedFormat(m_params.dst.image.format);
1092
1093         const tcu::TextureFormat        srcTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1094         const tcu::TextureFormat        dstTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1095
1096         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1097                                                                                                                                                                 (int)m_params.src.image.extent.width,
1098                                                                                                                                                                 (int)m_params.src.image.extent.height,
1099                                                                                                                                                                 (int)m_params.src.image.extent.depth));
1100         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);
1101         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1102                                                                                                                                                                 (int)m_params.dst.image.extent.width,
1103                                                                                                                                                                 (int)m_params.dst.image.extent.height,
1104                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
1105         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);
1106         generateExpectedResult();
1107
1108         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1109         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1110
1111         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1112         const VkDevice                          vkDevice                        = m_context.getDevice();
1113         const VkQueue                           queue                           = m_context.getUniversalQueue();
1114
1115         std::vector<VkImageCopy>                imageCopies;
1116         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
1117         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1118         {
1119                 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1120
1121                 // When copying between compressed and uncompressed formats the extent
1122                 // members represent the texel dimensions of the source image.
1123                 if (srcCompressed)
1124                 {
1125                         const deUint32  blockWidth      = getBlockWidth(m_params.src.image.format);
1126                         const deUint32  blockHeight     = getBlockHeight(m_params.src.image.format);
1127
1128                         imageCopy.srcOffset.x *= blockWidth;
1129                         imageCopy.srcOffset.y *= blockHeight;
1130                         imageCopy.extent.width *= blockWidth;
1131                         imageCopy.extent.height *= blockHeight;
1132                 }
1133
1134                 if (dstCompressed)
1135                 {
1136                         const deUint32  blockWidth      = getBlockWidth(m_params.dst.image.format);
1137                         const deUint32  blockHeight     = getBlockHeight(m_params.dst.image.format);
1138
1139                         imageCopy.dstOffset.x *= blockWidth;
1140                         imageCopy.dstOffset.y *= blockHeight;
1141                 }
1142
1143                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1144                 {
1145                         imageCopies.push_back(imageCopy);
1146                 }
1147                 else
1148                 {
1149                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1150                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1151                 }
1152         }
1153
1154         const VkImageMemoryBarrier      imageBarriers[]         =
1155         {
1156                 // source 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_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1162                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1163                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1164                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1165                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1166                         m_source.get(),                                                         // VkImage                                      image;
1167                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1168                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1169                                 0u,                                                             // deUint32                             baseMipLevel;
1170                                 1u,                                                             // deUint32                             mipLevels;
1171                                 0u,                                                             // deUint32                             baseArraySlice;
1172                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
1173                         }
1174                 },
1175                 // destination image
1176                 {
1177                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1178                         DE_NULL,                                                                        // const void*                          pNext;
1179                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1180                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1181                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1182                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1183                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1184                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1185                         m_destination.get(),                                            // VkImage                                      image;
1186                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1187                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1188                                 0u,                                                             // deUint32                             baseMipLevel;
1189                                 1u,                                                             // deUint32                             mipLevels;
1190                                 0u,                                                             // deUint32                             baseArraySlice;
1191                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
1192                         }
1193                 },
1194         };
1195
1196         beginCommandBuffer(vk, *m_cmdBuffer);
1197         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);
1198
1199         if (m_params.clearDestination)
1200         {
1201                 VkImageSubresourceRange range           = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1202                 VkClearColorValue               clearColor;
1203
1204                 clearColor.float32[0] = 1.0f;
1205                 clearColor.float32[1] = 1.0f;
1206                 clearColor.float32[2] = 1.0f;
1207                 clearColor.float32[3] = 1.0f;
1208                 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1209         }
1210
1211         if (m_params.extensionUse == EXTENSION_USE_NONE)
1212         {
1213                 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());
1214         }
1215         else
1216         {
1217                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1218                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1219                 {
1220                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
1221                         DE_NULL,                                                                        // const void*                          pNext;
1222                         m_source.get(),                                                         // VkImage                                      srcImage;
1223                         m_params.src.image.operationLayout,                     // VkImageLayout                        srcImageLayout;
1224                         m_destination.get(),                                            // VkImage                                      dstImage;
1225                         m_params.dst.image.operationLayout,                     // VkImageLayout                        dstImageLayout;
1226                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
1227                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
1228                 };
1229
1230                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1231         }
1232
1233         endCommandBuffer(vk, *m_cmdBuffer);
1234
1235         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1236
1237         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
1238
1239         return checkTestResult(resultTextureLevel->getAccess());
1240 }
1241
1242 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1243 {
1244         const tcu::Vec4 fThreshold (0.0f);
1245         const tcu::UVec4 uThreshold (0u);
1246
1247         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1248         {
1249                 if (tcu::hasDepthComponent(result.getFormat().order))
1250                 {
1251                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1252                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1253                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1254
1255                         if (isFloatFormat(result.getFormat()))
1256                         {
1257                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1258                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1259                         }
1260                         else
1261                         {
1262                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1263                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1264                         }
1265                 }
1266
1267                 if (tcu::hasStencilComponent(result.getFormat().order))
1268                 {
1269                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1270                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1271                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1272
1273                         if (isFloatFormat(result.getFormat()))
1274                         {
1275                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1276                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1277                         }
1278                         else
1279                         {
1280                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1281                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1282                         }
1283                 }
1284         }
1285         else
1286         {
1287                 if (isFloatFormat(result.getFormat()))
1288                 {
1289                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1290                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1291                 }
1292                 else
1293                 {
1294                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1295                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1296                 }
1297         }
1298
1299         return tcu::TestStatus::pass("CopiesAndBlitting test");
1300 }
1301
1302 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1303 {
1304         DE_UNREF(mipLevel);
1305
1306         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1307         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1308         VkExtent3D      extent          = region.imageCopy.extent;
1309
1310         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1311         {
1312                 dstOffset.z = srcOffset.z;
1313                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1314         }
1315         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1316         {
1317                 srcOffset.z = dstOffset.z;
1318                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1319         }
1320
1321
1322         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1323         {
1324                 DE_ASSERT(src.getFormat() == dst.getFormat());
1325
1326                 // Copy depth.
1327                 if (tcu::hasDepthComponent(src.getFormat().order))
1328                 {
1329                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1330                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1331                         tcu::copy(dstSubRegion, srcSubRegion);
1332                 }
1333
1334                 // Copy stencil.
1335                 if (tcu::hasStencilComponent(src.getFormat().order))
1336                 {
1337                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1338                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1339                         tcu::copy(dstSubRegion, srcSubRegion);
1340                 }
1341         }
1342         else
1343         {
1344                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1345                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1346                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1347                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1348
1349                 tcu::copy(dstSubRegion, srcSubRegion);
1350         }
1351 }
1352
1353 class CopyImageToImageTestCase : public vkt::TestCase
1354 {
1355 public:
1356                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
1357                                                                                                                  const std::string&                             name,
1358                                                                                                                  const std::string&                             description,
1359                                                                                                                  const TestParams                               params)
1360                                                                 : vkt::TestCase (testCtx, name, description)
1361                                                                 , m_params              (params)
1362         {}
1363
1364         virtual TestInstance*   createInstance                          (Context&                                               context) const
1365         {
1366                 return new CopyImageToImage(context, m_params);
1367         }
1368
1369         virtual void                    checkSupport                            (Context&                                               context) const
1370         {
1371                 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1372                 {
1373                         if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1374                                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1375                 }
1376
1377                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1378                 {
1379                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1380                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1381                 }
1382
1383                 if (m_params.separateDepthStencilLayouts)
1384                         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1385                                 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1386
1387                 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1388                         (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1389                 {
1390                         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1391                                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1392                 }
1393
1394                 const VkPhysicalDeviceLimits    limits          = context.getDeviceProperties().limits;
1395                 VkImageFormatProperties                 properties;
1396
1397                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1398                                                                                                                                                                         m_params.src.image.format,
1399                                                                                                                                                                         m_params.src.image.imageType,
1400                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1401                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1402                                                                                                                                                                         0,
1403                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1404                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1405                                                                                                                                                                         m_params.dst.image.format,
1406                                                                                                                                                                         m_params.dst.image.imageType,
1407                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1408                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1409                                                                                                                                                                         0,
1410                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1411                 {
1412                         TCU_THROW(NotSupportedError, "Format not supported");
1413                 }
1414
1415                 // Check maxImageDimension1D
1416                 {
1417                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1418                                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1419
1420                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1421                                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1422                 }
1423
1424                 // Check maxImageDimension2D
1425                 {
1426                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1427                                 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1428                         {
1429                                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1430                         }
1431
1432                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1433                                 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1434                         {
1435                                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1436                         }
1437                 }
1438
1439                 // Check maxImageDimension3D
1440                 {
1441                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1442                                 || m_params.src.image.extent.height > limits.maxImageDimension3D
1443                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1444                         {
1445                                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1446                         }
1447
1448                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1449                                 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1450                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1451                         {
1452                                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1453                         }
1454                 }
1455         }
1456
1457 private:
1458         TestParams                              m_params;
1459 };
1460
1461 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1462 {
1463 public:
1464                                                                                 CopyImageToImageMipmap          (Context&       context,
1465                                                                                                                                          TestParams params);
1466         virtual tcu::TestStatus                         iterate                                         (void);
1467
1468 protected:
1469         tcu::TestStatus                                         checkResult                                     (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1470
1471 private:
1472         Move<VkImage>                                           m_source;
1473         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1474         Move<VkImage>                                           m_destination;
1475         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1476
1477         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1478
1479 };
1480
1481 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1482         : CopiesAndBlittingTestInstance(context, params)
1483 {
1484         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1485         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1486         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1487         const VkDevice                          vkDevice                        = context.getDevice();
1488         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1489         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1490
1491         // Create source image
1492         {
1493                 const VkImageCreateInfo sourceImageParams               =
1494                 {
1495                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1496                         DE_NULL,                                                                // const void*                  pNext;
1497                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1498                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1499                         m_params.src.image.format,                              // VkFormat                             format;
1500                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1501                         params.mipLevels,                                               // deUint32                             mipLevels;
1502                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1503                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1504                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1505                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1506                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1507                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1508                         1u,                                                                             // deUint32                             queueFamilyCount;
1509                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1510                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1511                 };
1512
1513                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
1514                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1515                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1516         }
1517
1518         // Create destination image
1519         {
1520                 const VkImageCreateInfo destinationImageParams  =
1521                 {
1522                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1523                         DE_NULL,                                                                // const void*                  pNext;
1524                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1525                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1526                         m_params.dst.image.format,                              // VkFormat                             format;
1527                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1528                         params.mipLevels,                                               // deUint32                             mipLevels;
1529                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1530                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1531                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1532                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1533                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1534                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1535                         1u,                                                                             // deUint32                             queueFamilyCount;
1536                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1537                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1538                 };
1539
1540                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1541                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1542                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1543         }
1544 }
1545
1546 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1547 {
1548         const bool                                      srcCompressed           = isCompressedFormat(m_params.src.image.format);
1549         const bool                                      dstCompressed           = isCompressedFormat(m_params.dst.image.format);
1550
1551         const tcu::TextureFormat        srcTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1552         const tcu::TextureFormat        dstTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1553
1554         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1555                                                                                                                                                                 (int)m_params.src.image.extent.width,
1556                                                                                                                                                                 (int)m_params.src.image.extent.height,
1557                                                                                                                                                                 (int)m_params.src.image.extent.depth));
1558         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);
1559         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1560
1561         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1562                                                                                                                                                                          (int)m_params.dst.image.extent.width,
1563                                                                                                                                                                          (int)m_params.dst.image.extent.height,
1564                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
1565         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1566         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1567
1568         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1569         const VkDevice                          vkDevice                        = m_context.getDevice();
1570         const VkQueue                           queue                           = m_context.getUniversalQueue();
1571
1572         std::vector<VkImageCopy>                imageCopies;
1573         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
1574         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1575         {
1576                 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1577
1578                 // When copying between compressed and uncompressed formats the extent
1579                 // members represent the texel dimensions of the source image.
1580                 if (srcCompressed)
1581                 {
1582                         const deUint32  blockWidth      = getBlockWidth(m_params.src.image.format);
1583                         const deUint32  blockHeight     = getBlockHeight(m_params.src.image.format);
1584
1585                         imageCopy.srcOffset.x *= blockWidth;
1586                         imageCopy.srcOffset.y *= blockHeight;
1587                         imageCopy.extent.width *= blockWidth;
1588                         imageCopy.extent.height *= blockHeight;
1589                 }
1590
1591                 if (dstCompressed)
1592                 {
1593                         const deUint32  blockWidth      = getBlockWidth(m_params.dst.image.format);
1594                         const deUint32  blockHeight     = getBlockHeight(m_params.dst.image.format);
1595
1596                         imageCopy.dstOffset.x *= blockWidth;
1597                         imageCopy.dstOffset.y *= blockHeight;
1598                 }
1599
1600                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1601                 {
1602                         imageCopies.push_back(imageCopy);
1603                 }
1604                 else
1605                 {
1606                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1607                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1608                 }
1609         }
1610
1611         const VkImageMemoryBarrier      imageBarriers[]         =
1612         {
1613                 // source image
1614                 {
1615                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1616                         DE_NULL,                                                                        // const void*                          pNext;
1617                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1618                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1619                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1620                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1621                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1622                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1623                         m_source.get(),                                                         // VkImage                                      image;
1624                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1625                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1626                                 0u,                                                             // deUint32                             baseMipLevel;
1627                                 m_params.mipLevels,                             // deUint32                             mipLevels;
1628                                 0u,                                                             // deUint32                             baseArraySlice;
1629                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
1630                         }
1631                 },
1632                 // destination image
1633                 {
1634                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1635                         DE_NULL,                                                                        // const void*                          pNext;
1636                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1637                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1638                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1639                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1640                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1641                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1642                         m_destination.get(),                                            // VkImage                                      image;
1643                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1644                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1645                                 0u,                                                             // deUint32                             baseMipLevel;
1646                                 m_params.mipLevels,                             // deUint32                             mipLevels;
1647                                 0u,                                                             // deUint32                             baseArraySlice;
1648                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
1649                         }
1650                 },
1651         };
1652
1653         beginCommandBuffer(vk, *m_cmdBuffer);
1654         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);
1655
1656         if (m_params.extensionUse == EXTENSION_USE_NONE)
1657         {
1658                 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());
1659         }
1660         else
1661         {
1662                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1663                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1664                 {
1665                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
1666                         DE_NULL,                                                                        // const void*                          pNext;
1667                         m_source.get(),                                                         // VkImage                                      srcImage;
1668                         m_params.src.image.operationLayout,                     // VkImageLayout                        srcImageLayout;
1669                         m_destination.get(),                                            // VkImage                                      dstImage;
1670                         m_params.dst.image.operationLayout,                     // VkImageLayout                        dstImageLayout;
1671                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
1672                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
1673                 };
1674
1675                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1676         }
1677
1678         endCommandBuffer(vk, *m_cmdBuffer);
1679
1680         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1681
1682         for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1683         {
1684                 de::MovePtr<tcu::TextureLevel>  resultTextureLevel              = readImage(*m_destination, m_params.dst.image, miplevel);
1685                 de::MovePtr<tcu::TextureLevel>  expectedTextureLevel    = readImage(*m_source, m_params.src.image, miplevel);
1686
1687                 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1688                 if (result.getCode() != QP_TEST_RESULT_PASS)
1689                         return result;
1690         }
1691         return tcu::TestStatus::pass("Pass");
1692 }
1693
1694 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1695 {
1696         const tcu::Vec4 fThreshold (0.0f);
1697         const tcu::UVec4 uThreshold (0u);
1698
1699         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1700         {
1701                 if (tcu::hasDepthComponent(result.getFormat().order))
1702                 {
1703                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1704                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1705                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(expected, mode);
1706
1707                         if (isFloatFormat(result.getFormat()))
1708                         {
1709                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1710                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1711                         }
1712                         else
1713                         {
1714                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1715                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1716                         }
1717                 }
1718
1719                 if (tcu::hasStencilComponent(result.getFormat().order))
1720                 {
1721                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1722                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1723                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(expected, mode);
1724
1725                         if (isFloatFormat(result.getFormat()))
1726                         {
1727                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1728                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1729                         }
1730                         else
1731                         {
1732                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1733                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1734                         }
1735                 }
1736         }
1737         else
1738         {
1739                 if (isFloatFormat(result.getFormat()))
1740                 {
1741                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1742                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1743                 }
1744                 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1745                 {
1746                         // There may be an ambiguity between two possible binary representations of 1.0.
1747                         // Get rid of that by expanding the data to floats and re-normalizing again.
1748
1749                         tcu::TextureLevel resultSnorm   (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1750                         {
1751                                 tcu::TextureLevel resultFloat   (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1752
1753                                 tcu::copy(resultFloat.getAccess(), result);
1754                                 tcu::copy(resultSnorm, resultFloat.getAccess());
1755                         }
1756
1757                         tcu::TextureLevel expectedSnorm (expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1758
1759                         {
1760                                 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1761
1762                                 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1763                                 tcu::copy(expectedSnorm, expectedFloat.getAccess());
1764                         }
1765
1766                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1767                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1768                 }
1769                 else
1770                 {
1771                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1772                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1773                 }
1774         }
1775
1776         return tcu::TestStatus::pass("CopiesAndBlitting test");
1777 }
1778
1779 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1780 {
1781         DE_UNREF(mipLevel);
1782
1783         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1784         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1785         VkExtent3D      extent          = region.imageCopy.extent;
1786
1787         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1788         {
1789                 dstOffset.z = srcOffset.z;
1790                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1791         }
1792         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1793         {
1794                 srcOffset.z = dstOffset.z;
1795                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1796         }
1797
1798
1799         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1800         {
1801                 DE_ASSERT(src.getFormat() == dst.getFormat());
1802
1803                 // Copy depth.
1804                 if (tcu::hasDepthComponent(src.getFormat().order))
1805                 {
1806                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1807                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1808                         tcu::copy(dstSubRegion, srcSubRegion);
1809                 }
1810
1811                 // Copy stencil.
1812                 if (tcu::hasStencilComponent(src.getFormat().order))
1813                 {
1814                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1815                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1816                         tcu::copy(dstSubRegion, srcSubRegion);
1817                 }
1818         }
1819         else
1820         {
1821                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1822                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1823                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1824                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1825
1826                 tcu::copy(dstSubRegion, srcSubRegion);
1827         }
1828 }
1829
1830 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1831 {
1832 public:
1833                                                         CopyImageToImageMipmapTestCase  (tcu::TestContext&                              testCtx,
1834                                                                                                                          const std::string&                             name,
1835                                                                                                                          const std::string&                             description,
1836                                                                                                                          const TestParams                               params)
1837                                                                 : vkt::TestCase (testCtx, name, description)
1838                                                                 , m_params              (params)
1839         {}
1840
1841         virtual TestInstance*   createInstance                          (Context&                                               context) const
1842         {
1843                 return new CopyImageToImageMipmap(context, m_params);
1844         }
1845
1846         virtual void                    checkSupport                            (Context&                                               context) const
1847         {
1848                 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1849                 {
1850                         if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1851                                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1852                 }
1853
1854                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1855                 {
1856                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1857                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1858                 }
1859
1860                 if (m_params.separateDepthStencilLayouts)
1861                         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1862                                 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1863
1864                 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1865                         (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1866                 {
1867                         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1868                                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1869                 }
1870
1871                 const VkPhysicalDeviceLimits    limits          = context.getDeviceProperties().limits;
1872                 VkImageFormatProperties                 properties;
1873
1874                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1875                                                                                                                                                                         m_params.src.image.format,
1876                                                                                                                                                                         m_params.src.image.imageType,
1877                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1878                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1879                                                                                                                                                                         0,
1880                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1881                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1882                                                                                                                                                                         m_params.dst.image.format,
1883                                                                                                                                                                         m_params.dst.image.imageType,
1884                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1885                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1886                                                                                                                                                                         0,
1887                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1888                 {
1889                         TCU_THROW(NotSupportedError, "Format not supported");
1890                 }
1891
1892                 // Check maxImageDimension1D
1893                 {
1894                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1895                                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1896
1897                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1898                                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1899                 }
1900
1901                 // Check maxImageDimension2D
1902                 {
1903                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1904                                 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1905                         {
1906                                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1907                         }
1908
1909                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1910                                 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1911                         {
1912                                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1913                         }
1914                 }
1915
1916                 // Check maxImageDimension3D
1917                 {
1918                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1919                                 || m_params.src.image.extent.height > limits.maxImageDimension3D
1920                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1921                         {
1922                                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1923                         }
1924
1925                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1926                                 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1927                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1928                         {
1929                                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1930                         }
1931                 }
1932         }
1933
1934 private:
1935         TestParams                              m_params;
1936 };
1937
1938 // Copy from buffer to buffer.
1939
1940 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1941 {
1942 public:
1943                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
1944         virtual tcu::TestStatus         iterate                                         (void);
1945 private:
1946         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1947         Move<VkBuffer>                          m_source;
1948         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1949         Move<VkBuffer>                          m_destination;
1950         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1951 };
1952
1953 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1954         : CopiesAndBlittingTestInstance (context, params)
1955 {
1956         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1957         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1958         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1959         const VkDevice                          vkDevice                        = context.getDevice();
1960         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1961         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1962
1963         // Create source buffer
1964         {
1965                 const VkBufferCreateInfo        sourceBufferParams              =
1966                 {
1967                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1968                         DE_NULL,                                                                        // const void*                  pNext;
1969                         0u,                                                                                     // VkBufferCreateFlags  flags;
1970                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
1971                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1972                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1973                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1974                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1975                 };
1976
1977                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1978                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1979                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1980         }
1981
1982         // Create destination buffer
1983         {
1984                 const VkBufferCreateInfo        destinationBufferParams =
1985                 {
1986                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1987                         DE_NULL,                                                                        // const void*                  pNext;
1988                         0u,                                                                                     // VkBufferCreateFlags  flags;
1989                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
1990                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1991                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1992                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1993                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1994                 };
1995
1996                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1997                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1998                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1999         }
2000 }
2001
2002 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2003 {
2004         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
2005         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2006         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2007
2008         const int dstLevelWidth         = (int)(m_params.dst.buffer.size/4);
2009         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2010         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2011
2012         generateExpectedResult();
2013
2014         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2015         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2016
2017         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2018         const VkDevice                          vkDevice        = m_context.getDevice();
2019         const VkQueue                           queue           = m_context.getUniversalQueue();
2020
2021         const VkBufferMemoryBarrier             srcBufferBarrier        =
2022         {
2023                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2024                 DE_NULL,                                                                        // const void*          pNext;
2025                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
2026                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
2027                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2028                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2029                 *m_source,                                                                      // VkBuffer                     buffer;
2030                 0u,                                                                                     // VkDeviceSize         offset;
2031                 m_params.src.buffer.size                                        // VkDeviceSize         size;
2032         };
2033
2034         const VkBufferMemoryBarrier             dstBufferBarrier        =
2035         {
2036                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2037                 DE_NULL,                                                                        // const void*          pNext;
2038                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
2039                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
2040                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2041                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2042                 *m_destination,                                                         // VkBuffer                     buffer;
2043                 0u,                                                                                     // VkDeviceSize         offset;
2044                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
2045         };
2046
2047         std::vector<VkBufferCopy>               bufferCopies;
2048         std::vector<VkBufferCopy2KHR>   bufferCopies2KHR;
2049         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2050         {
2051                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2052                 {
2053                         bufferCopies.push_back(m_params.regions[i].bufferCopy);
2054                 }
2055                 else
2056                 {
2057                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2058                         bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2059                 }
2060         }
2061
2062         beginCommandBuffer(vk, *m_cmdBuffer);
2063         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);
2064
2065         if (m_params.extensionUse == EXTENSION_USE_NONE)
2066         {
2067                 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2068         }
2069         else
2070         {
2071                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2072                 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2073                 {
2074                         VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,       // VkStructureType                      sType;
2075                         DE_NULL,                                                                        // const void*                          pNext;
2076                         m_source.get(),                                                         // VkBuffer                                     srcBuffer;
2077                         m_destination.get(),                                            // VkBuffer                                     dstBuffer;
2078                         (deUint32)m_params.regions.size(),                      // uint32_t                                     regionCount;
2079                         &bufferCopies2KHR[0]                                            // const VkBufferCopy2KHR*      pRegions;
2080                 };
2081
2082                 vk.cmdCopyBuffer2KHR(*m_cmdBuffer, &copyBufferInfo2KHR);
2083         }
2084
2085         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);
2086         endCommandBuffer(vk, *m_cmdBuffer);
2087         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2088
2089         // Read buffer data
2090         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2091         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2092         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2093
2094         return checkTestResult(resultLevel->getAccess());
2095 }
2096
2097 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2098 {
2099         DE_UNREF(mipLevel);
2100
2101         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2102                          (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2103                          (size_t)region.bufferCopy.size);
2104 }
2105
2106 class BufferToBufferTestCase : public vkt::TestCase
2107 {
2108 public:
2109                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
2110                                                                                                          const std::string&     name,
2111                                                                                                          const std::string&     description,
2112                                                                                                          const TestParams       params)
2113                                                                 : vkt::TestCase (testCtx, name, description)
2114                                                                 , m_params              (params)
2115                                                         {}
2116
2117         virtual TestInstance*   createInstance                  (Context& context) const
2118                                                         {
2119                                                                 return new CopyBufferToBuffer(context, m_params);
2120                                                         }
2121
2122         virtual void                    checkSupport(Context&   context) const
2123         {
2124                                                         if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2125                                                         {
2126                                                                 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2127                                                                 {
2128                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2129                                                                 }
2130                                                         }
2131         }
2132
2133         private:
2134         TestParams                              m_params;
2135 };
2136
2137 // Copy from image to buffer.
2138
2139 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2140 {
2141 public:
2142                                                                 CopyImageToBuffer                       (Context&       context,
2143                                                                                                                          TestParams     testParams);
2144         virtual tcu::TestStatus         iterate                                         (void);
2145 private:
2146         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2147
2148         tcu::TextureFormat                      m_textureFormat;
2149         VkDeviceSize                            m_bufferSize;
2150
2151         Move<VkImage>                           m_source;
2152         de::MovePtr<Allocation>         m_sourceImageAlloc;
2153         Move<VkBuffer>                          m_destination;
2154         de::MovePtr<Allocation>         m_destinationBufferAlloc;
2155 };
2156
2157 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2158         : CopiesAndBlittingTestInstance(context, testParams)
2159         , m_textureFormat(mapVkFormat(testParams.src.image.format))
2160         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2161 {
2162         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2163         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2164         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2165         const VkDevice                          vkDevice                        = context.getDevice();
2166         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2167         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2168
2169         // Create source image
2170         {
2171                 const VkImageCreateInfo         sourceImageParams               =
2172                 {
2173                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2174                         DE_NULL,                                                                // const void*                  pNext;
2175                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
2176                         m_params.src.image.imageType,                   // VkImageType                  imageType;
2177                         m_params.src.image.format,                              // VkFormat                             format;
2178                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
2179                         1u,                                                                             // deUint32                             mipLevels;
2180                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
2181                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2182                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2183                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2184                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2185                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2186                         1u,                                                                             // deUint32                             queueFamilyCount;
2187                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2188                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2189                 };
2190
2191                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
2192                 m_sourceImageAlloc      = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2193                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2194         }
2195
2196         // Create destination buffer
2197         {
2198                 const VkBufferCreateInfo        destinationBufferParams =
2199                 {
2200                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2201                         DE_NULL,                                                                        // const void*                  pNext;
2202                         0u,                                                                                     // VkBufferCreateFlags  flags;
2203                         m_bufferSize,                                                           // VkDeviceSize                 size;
2204                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
2205                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2206                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2207                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2208                 };
2209
2210                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
2211                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2212                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2213         }
2214 }
2215
2216 tcu::TestStatus CopyImageToBuffer::iterate (void)
2217 {
2218         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2219                                                                                                                                                                 m_params.src.image.extent.width,
2220                                                                                                                                                                 m_params.src.image.extent.height,
2221                                                                                                                                                                 m_params.src.image.extent.depth));
2222         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2223         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2224         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2225
2226         generateExpectedResult();
2227
2228         uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2229         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2230
2231         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2232         const VkDevice                          vkDevice        = m_context.getDevice();
2233         const VkQueue                           queue           = m_context.getUniversalQueue();
2234
2235         // Barriers for copying image to buffer
2236         const VkImageMemoryBarrier              imageBarrier            =
2237         {
2238                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2239                 DE_NULL,                                                                        // const void*                          pNext;
2240                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2241                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
2242                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2243                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
2244                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2245                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2246                 *m_source,                                                                      // VkImage                                      image;
2247                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2248                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2249                         0u,                                                                     // deUint32                             baseMipLevel;
2250                         1u,                                                                     // deUint32                             mipLevels;
2251                         0u,                                                                     // deUint32                             baseArraySlice;
2252                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
2253                 }
2254         };
2255
2256         const VkBufferMemoryBarrier             bufferBarrier           =
2257         {
2258                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2259                 DE_NULL,                                                                        // const void*          pNext;
2260                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
2261                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
2262                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2263                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2264                 *m_destination,                                                         // VkBuffer                     buffer;
2265                 0u,                                                                                     // VkDeviceSize         offset;
2266                 m_bufferSize                                                            // VkDeviceSize         size;
2267         };
2268
2269         // Copy from image to buffer
2270         std::vector<VkBufferImageCopy>          bufferImageCopies;
2271         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2272         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2273         {
2274                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2275                 {
2276                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2277                 }
2278                 else
2279                 {
2280                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2281                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2282                 }
2283         }
2284
2285         beginCommandBuffer(vk, *m_cmdBuffer);
2286         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);
2287
2288         if (m_params.extensionUse == EXTENSION_USE_NONE)
2289         {
2290                 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2291         }
2292         else
2293         {
2294                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2295                 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2296                 {
2297                         VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,      // VkStructureType                              sType;
2298                         DE_NULL,                                                                                        // const void*                                  pNext;
2299                         m_source.get(),                                                                         // VkImage                                              srcImage;
2300                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                                srcImageLayout;
2301                         m_destination.get(),                                                            // VkBuffer                                             dstBuffer;
2302                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2303                         &bufferImageCopies2KHR[0]                                                       // const VkBufferImageCopy2KHR* pRegions;
2304                 };
2305
2306                 vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
2307         }
2308
2309         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);
2310         endCommandBuffer(vk, *m_cmdBuffer);
2311
2312         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2313
2314         // Read buffer data
2315         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2316         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2317         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2318
2319         return checkTestResult(resultLevel->getAccess());
2320 }
2321
2322 class CopyImageToBufferTestCase : public vkt::TestCase
2323 {
2324 public:
2325                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
2326                                                                                                                  const std::string&             name,
2327                                                                                                                  const std::string&             description,
2328                                                                                                                  const TestParams               params)
2329                                                                 : vkt::TestCase (testCtx, name, description)
2330                                                                 , m_params              (params)
2331                                                         {}
2332
2333         virtual TestInstance*   createInstance                          (Context&                               context) const
2334                                                         {
2335                                                                 return new CopyImageToBuffer(context, m_params);
2336                                                         }
2337
2338         virtual void                    checkSupport                            (Context&                               context) const
2339                                                         {
2340                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2341                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2342                                                                 {
2343                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2344                                                                 }
2345                                                         }
2346
2347 private:
2348         TestParams                              m_params;
2349 };
2350
2351 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2352 {
2353         DE_UNREF(mipLevel);
2354
2355         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2356         if (!rowLength)
2357                 rowLength = region.bufferImageCopy.imageExtent.width;
2358
2359         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
2360         if (!imageHeight)
2361                 imageHeight = region.bufferImageCopy.imageExtent.height;
2362
2363         const int                       texelSize               = src.getFormat().getPixelSize();
2364         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
2365         const VkOffset3D        srcOffset               = region.bufferImageCopy.imageOffset;
2366         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
2367         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2368
2369         for (deUint32 z = 0; z < extent.depth; z++)
2370         {
2371                 for (deUint32 y = 0; y < extent.height; y++)
2372                 {
2373                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
2374                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2375                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
2376                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2377                         tcu::copy(dstSubRegion, srcSubRegion);
2378                 }
2379         }
2380 }
2381
2382 // Copy from buffer to image.
2383
2384 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2385 {
2386 public:
2387                                                                 CopyBufferToImage                       (Context&       context,
2388                                                                                                                          TestParams     testParams);
2389         virtual tcu::TestStatus         iterate                                         (void);
2390
2391 private:
2392         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2393
2394         tcu::TextureFormat                      m_textureFormat;
2395         VkDeviceSize                            m_bufferSize;
2396
2397         Move<VkBuffer>                          m_source;
2398         de::MovePtr<Allocation>         m_sourceBufferAlloc;
2399         Move<VkImage>                           m_destination;
2400         de::MovePtr<Allocation>         m_destinationImageAlloc;
2401 };
2402
2403 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2404         : CopiesAndBlittingTestInstance(context, testParams)
2405         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2406         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2407 {
2408         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2409         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2410         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2411         const VkDevice                          vkDevice                        = context.getDevice();
2412         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2413         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2414
2415         // Create source buffer
2416         {
2417                 const VkBufferCreateInfo        sourceBufferParams              =
2418                 {
2419                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2420                         DE_NULL,                                                                        // const void*                  pNext;
2421                         0u,                                                                                     // VkBufferCreateFlags  flags;
2422                         m_bufferSize,                                                           // VkDeviceSize                 size;
2423                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
2424                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2425                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2426                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2427                 };
2428
2429                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
2430                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2431                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2432         }
2433
2434         // Create destination image
2435         {
2436                 const VkImageCreateInfo         destinationImageParams  =
2437                 {
2438                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2439                         DE_NULL,                                                                // const void*                  pNext;
2440                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2441                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2442                         m_params.dst.image.format,                              // VkFormat                             format;
2443                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2444                         1u,                                                                             // deUint32                             mipLevels;
2445                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2446                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2447                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2448                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2449                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2450                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2451                         1u,                                                                             // deUint32                             queueFamilyCount;
2452                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2453                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2454                 };
2455
2456                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
2457                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2458                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2459         }
2460 }
2461
2462 tcu::TestStatus CopyBufferToImage::iterate (void)
2463 {
2464         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2465         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2466         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2467                                                                                                                                                                         m_params.dst.image.extent.width,
2468                                                                                                                                                                         m_params.dst.image.extent.height,
2469                                                                                                                                                                         m_params.dst.image.extent.depth));
2470
2471         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2472
2473         generateExpectedResult();
2474
2475         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2476         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2477
2478         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2479         const VkDevice                          vkDevice        = m_context.getDevice();
2480         const VkQueue                           queue           = m_context.getUniversalQueue();
2481
2482         const VkImageMemoryBarrier      imageBarrier    =
2483         {
2484                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2485                 DE_NULL,                                                                        // const void*                          pNext;
2486                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2487                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2488                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2489                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2490                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2491                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2492                 *m_destination,                                                         // VkImage                                      image;
2493                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2494                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2495                         0u,                                                             // deUint32                             baseMipLevel;
2496                         1u,                                                             // deUint32                             mipLevels;
2497                         0u,                                                             // deUint32                             baseArraySlice;
2498                         getArraySize(m_params.dst.image)                                                                // deUint32                             arraySize;
2499                 }
2500         };
2501
2502         // Copy from buffer to image
2503         std::vector<VkBufferImageCopy>          bufferImageCopies;
2504         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2505         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2506         {
2507                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2508                 {
2509                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2510                 }
2511                 else
2512                 {
2513                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2514                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2515                 }
2516         }
2517
2518         beginCommandBuffer(vk, *m_cmdBuffer);
2519         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);
2520
2521         if (m_params.extensionUse == EXTENSION_USE_NONE)
2522         {
2523                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2524         }
2525         else
2526         {
2527                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2528                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2529                 {
2530                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2531                         DE_NULL,                                                                                        // const void*                                  pNext;
2532                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2533                         m_destination.get(),                                                            // VkImage                                              dstImage;
2534                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2535                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2536                         bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2537                 };
2538
2539                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2540         }
2541
2542
2543         endCommandBuffer(vk, *m_cmdBuffer);
2544
2545         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2546
2547         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
2548
2549         return checkTestResult(resultLevel->getAccess());
2550 }
2551
2552 class CopyBufferToImageTestCase : public vkt::TestCase
2553 {
2554 public:
2555                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
2556                                                                                                                  const std::string&             name,
2557                                                                                                                  const std::string&             description,
2558                                                                                                                  const TestParams               params)
2559                                                                 : vkt::TestCase (testCtx, name, description)
2560                                                                 , m_params              (params)
2561                                                         {}
2562
2563         virtual                                 ~CopyBufferToImageTestCase      (void) {}
2564
2565         virtual TestInstance*   createInstance                          (Context&                               context) const
2566                                                         {
2567                                                                 return new CopyBufferToImage(context, m_params);
2568                                                         }
2569
2570         virtual void                    checkSupport                            (Context&                               context) const
2571                                                         {
2572                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2573                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2574                                                                 {
2575                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2576                                                                 }
2577                                                         }
2578
2579
2580 private:
2581         TestParams                              m_params;
2582 };
2583
2584 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2585 {
2586         DE_UNREF(mipLevel);
2587
2588         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2589         if (!rowLength)
2590                 rowLength = region.bufferImageCopy.imageExtent.width;
2591
2592         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
2593         if (!imageHeight)
2594                 imageHeight = region.bufferImageCopy.imageExtent.height;
2595
2596         const int                       texelSize               = dst.getFormat().getPixelSize();
2597         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
2598         const VkOffset3D        dstOffset               = region.bufferImageCopy.imageOffset;
2599         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
2600         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2601
2602         for (deUint32 z = 0; z < extent.depth; z++)
2603         {
2604                 for (deUint32 y = 0; y < extent.height; y++)
2605                 {
2606                         int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2607                         const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2608                         const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2609                                                                                                                                                   region.bufferImageCopy.imageExtent.width, 1, 1);
2610                         tcu::copy(dstSubRegion, srcSubRegion);
2611                 }
2612         }
2613 }
2614
2615 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2616 {
2617 public:
2618                                                                 CopyBufferToDepthStencil        (Context& context,
2619                                                                                                                          TestParams     testParams);
2620         virtual tcu::TestStatus         iterate                                         (void);
2621 private:
2622         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2623
2624         tcu::TextureFormat                      m_textureFormat;
2625         VkDeviceSize                            m_bufferSize;
2626
2627         Move<VkBuffer>                          m_source;
2628         de::MovePtr<Allocation>         m_sourceBufferAlloc;
2629         Move<VkImage>                           m_destination;
2630         de::MovePtr<Allocation>         m_destinationImageAlloc;
2631 };
2632
2633 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2634 {
2635         DE_UNREF(mipLevel);
2636
2637         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2638         if (!rowLength)
2639                 rowLength = region.bufferImageCopy.imageExtent.width;
2640
2641         deUint32                        imageHeight = region.bufferImageCopy.bufferImageHeight;
2642         if (!imageHeight)
2643                 imageHeight = region.bufferImageCopy.imageExtent.height;
2644
2645         const int                       texelSize       = dst.getFormat().getPixelSize();
2646         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
2647         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
2648         const int                       texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2649
2650         for (deUint32 z = 0; z < extent.depth; z++)
2651         {
2652                 for (deUint32 y = 0; y < extent.height; y++)
2653                 {
2654                         int                                                                     texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2655                         const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2656                         const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2657                                 region.bufferImageCopy.imageExtent.width, 1, 1);
2658
2659                         if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2660                         {
2661                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2662                         }
2663                         else
2664                         {
2665                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2666                         }
2667                 }
2668         }
2669 }
2670
2671 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2672 {
2673         VkFormatProperties formatProps;
2674         vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2675         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2676 }
2677
2678 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2679         : CopiesAndBlittingTestInstance(context, testParams)
2680         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2681         , m_bufferSize(0)
2682 {
2683         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2684         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2685         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2686         const VkDevice                          vkDevice                        = context.getDevice();
2687         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2688         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2689         const bool                                      hasDepth                        = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2690         const bool                                      hasStencil                      = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2691
2692         if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2693         {
2694                 TCU_THROW(NotSupportedError, "Image format not supported.");
2695         }
2696
2697         if (hasDepth)
2698         {
2699                 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2700                 if (texelSize > sizeof(float))
2701                 {
2702                         // We must have D32F_S8 format, depth must be packed so we only need
2703                         // to allocate space for the D32F part. Stencil will be separate
2704                         texelSize = sizeof(float);
2705                 }
2706                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2707         }
2708         if (hasStencil)
2709         {
2710                 // Stencil is always 8bits and packed.
2711                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2712         }
2713
2714         // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2715         {
2716                 const VkBufferCreateInfo        sourceBufferParams              =
2717                 {
2718                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2719                         DE_NULL,                                                                        // const void*                  pNext;
2720                         0u,                                                                                     // VkBufferCreateFlags  flags;
2721                         m_bufferSize,                                                           // VkDeviceSize                 size;
2722                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
2723                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2724                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2725                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2726                 };
2727
2728                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
2729                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2730                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2731         }
2732
2733         // Create destination image
2734         {
2735                 const VkImageCreateInfo         destinationImageParams  =
2736                 {
2737                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2738                         DE_NULL,                                                                // const void*                  pNext;
2739                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2740                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2741                         m_params.dst.image.format,                              // VkFormat                             format;
2742                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2743                         1u,                                                                             // deUint32                             mipLevels;
2744                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2745                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2746                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2747                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2748                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2749                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2750                         1u,                                                                             // deUint32                             queueFamilyCount;
2751                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2752                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2753                 };
2754
2755                 m_destination                           = createImage(vk, vkDevice, &destinationImageParams);
2756                 m_destinationImageAlloc         = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2757                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2758         }
2759 }
2760
2761 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2762 {
2763         // Create source depth/stencil content. Treat as 1D texture to get different pattern
2764         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2765         // Fill buffer with linear gradiant
2766         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2767
2768         // Create image layer for depth/stencil
2769         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2770                 m_params.dst.image.extent.width,
2771                 m_params.dst.image.extent.height,
2772                 m_params.dst.image.extent.depth));
2773
2774         // Fill image layer with 2D gradiant
2775         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2776
2777         // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2778         // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2779         // This emulates what the HW will be doing.
2780         generateExpectedResult();
2781
2782         // Upload our source depth/stencil content to the source buffer
2783         // This is the buffer that will be used by region commands
2784         std::vector<VkBufferImageCopy>          bufferImageCopies;
2785         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2786         VkDeviceSize                                    bufferOffset    = 0;
2787         const VkDevice                                  vkDevice                = m_context.getDevice();
2788         const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
2789         const VkQueue                                   queue                   = m_context.getUniversalQueue();
2790         char*                                                   dstPtr                  = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2791         bool                                                    depthLoaded             = DE_FALSE;
2792         bool                                                    stencilLoaded   = DE_FALSE;
2793         VkDeviceSize                                    depthOffset             = 0;
2794         VkDeviceSize                                    stencilOffset   = 0;
2795
2796         // To be able to test ordering depth & stencil differently
2797         // we take the given copy regions and use that as the desired order
2798         // and copy the appropriate data into place and compute the appropriate
2799         // data offsets to be used in the copy command.
2800         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2801         {
2802                 tcu::ConstPixelBufferAccess bufferAccess        = m_sourceTextureLevel->getAccess();
2803                 deUint32                                        bufferSize              = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2804                 VkBufferImageCopy                       copyData                = m_params.regions[i].bufferImageCopy;
2805                 char*                                           srcPtr;
2806
2807                 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2808                 {
2809                         // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2810                         tcu::TextureLevel       depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2811                         bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2812                         // Copy depth component only from source data. This gives us packed depth-only data.
2813                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2814                         srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2815                         // Copy packed depth-only data to output buffer
2816                         deMemcpy(dstPtr, srcPtr, bufferSize);
2817                         depthLoaded = DE_TRUE;
2818                         depthOffset = bufferOffset;
2819                         dstPtr += bufferSize;
2820                         bufferOffset += bufferSize;
2821                         copyData.bufferOffset += depthOffset;
2822                 }
2823                 else if (!stencilLoaded)
2824                 {
2825                         // Create level that is same component as stencil buffer (always 8-bits)
2826                         tcu::TextureLevel       stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2827                         // Copy stencil component only from source data. This gives us packed stencil-only data.
2828                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2829                         srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2830                         // Copy packed stencil-only data to output buffer
2831                         deMemcpy(dstPtr, srcPtr, bufferSize);
2832                         stencilLoaded = DE_TRUE;
2833                         stencilOffset = bufferOffset;
2834                         dstPtr += bufferSize;
2835                         bufferOffset += bufferSize;
2836
2837                         // Reference image generation uses pixel offsets based on buffer offset.
2838                         // We need to adjust the offset now that the stencil data is not interleaved.
2839                         copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2840
2841                         copyData.bufferOffset += stencilOffset;
2842                 }
2843
2844                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2845                 {
2846                         bufferImageCopies.push_back(copyData);
2847                 }
2848                 else
2849                 {
2850                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2851                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2852                 }
2853         }
2854
2855         flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2856
2857         // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2858         // depth and stencil to known values.
2859         // Uses uploadImageAspect so makes its own buffers for depth and stencil
2860         // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2861         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2862
2863         const VkImageMemoryBarrier      imageBarrier    =
2864         {
2865                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2866                 DE_NULL,                                                                        // const void*                          pNext;
2867                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2868                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2869                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2870                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2871                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2872                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2873                 *m_destination,                                                         // VkImage                                      image;
2874                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2875                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2876                         0u,                                                             // deUint32                             baseMipLevel;
2877                         1u,                                                             // deUint32                             mipLevels;
2878                         0u,                                                             // deUint32                             baseArraySlice;
2879                         1u                                                              // deUint32                             arraySize;
2880                 }
2881         };
2882
2883         // Copy from buffer to depth/stencil image
2884
2885         beginCommandBuffer(vk, *m_cmdBuffer);
2886         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);
2887
2888         if (m_params.extensionUse == EXTENSION_USE_NONE)
2889         {
2890                 if (m_params.singleCommand)
2891                 {
2892                         // Issue a single copy command with regions defined by the test.
2893                         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2894                 }
2895                 else
2896                 {
2897                         // Issue a a copy command per region defined by the test.
2898                         for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2899                         {
2900                                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2901                         }
2902                 }
2903         }
2904         else
2905         {
2906                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2907
2908                 if (m_params.singleCommand)
2909                 {
2910                         // Issue a single copy command with regions defined by the test.
2911                         const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2912                         {
2913                                 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2914                                 DE_NULL,                                                                                        // const void*                                  pNext;
2915                                 m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2916                                 m_destination.get(),                                                            // VkImage                                              dstImage;
2917                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2918                                 (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2919                                 bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2920                         };
2921                         vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2922                 }
2923                 else
2924                 {
2925                         // Issue a a copy command per region defined by the test.
2926                         for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2927                         {
2928                                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2929                                 {
2930                                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2931                                         DE_NULL,                                                                                        // const void*                                  pNext;
2932                                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2933                                         m_destination.get(),                                                            // VkImage                                              dstImage;
2934                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2935                                         1,                                                                                                      // uint32_t                                             regionCount;
2936                                         &bufferImageCopies2KHR[i]                                                       // const VkBufferImageCopy2KHR* pRegions;
2937                                 };
2938                                 // Issue a single copy command with regions defined by the test.
2939                                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2940                         }
2941                 }
2942         }
2943         endCommandBuffer(vk, *m_cmdBuffer);
2944
2945         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2946
2947         de::MovePtr<tcu::TextureLevel>  resultLevel = readImage(*m_destination, m_params.dst.image);
2948
2949         // For combined depth/stencil formats both aspects are checked even when the test only
2950         // copies one. Clear such aspects here for both the result and the reference.
2951         if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2952         {
2953                 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2954                 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2955         }
2956         if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2957         {
2958                 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2959                 tcu::clearStencil(resultLevel->getAccess(), 0);
2960         }
2961
2962         return checkTestResult(resultLevel->getAccess());
2963 }
2964
2965 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
2966 {
2967 public:
2968                                                         CopyBufferToDepthStencilTestCase        (tcu::TestContext&              testCtx,
2969                                                                                                                                  const std::string&             name,
2970                                                                                                                                  const std::string&             description,
2971                                                                                                                                  const TestParams               params)
2972                                                                 : vkt::TestCase(testCtx, name, description)
2973                                                                 , m_params(params)
2974                                                         {}
2975
2976         virtual                                 ~CopyBufferToDepthStencilTestCase       (void) {}
2977
2978         virtual TestInstance*   createInstance                                          (Context&                               context) const
2979                                                         {
2980                                                                 return new CopyBufferToDepthStencil(context, m_params);
2981                                                         }
2982
2983         virtual void                    checkSupport                                            (Context&                               context) const
2984                                                         {
2985                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2986                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2987                                                                 {
2988                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2989                                                                 }
2990                                                         }
2991
2992 private:
2993         TestParams                              m_params;
2994 };
2995
2996 // CompressedTextureForBlit is a helper class that stores compressed texture data.
2997 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
2998 // and has special cases needed for blits to some formats.
2999
3000 class CompressedTextureForBlit
3001 {
3002 public:
3003         CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat);
3004
3005         tcu::PixelBufferAccess                  getDecompressedAccess() const;
3006         const tcu::CompressedTexture&   getCompressedTexture() const;
3007
3008 protected:
3009
3010         tcu::CompressedTexture          m_compressedTexture;
3011         de::ArrayBuffer<deUint8>        m_decompressedData;
3012         tcu::PixelBufferAccess          m_decompressedAccess;
3013 };
3014
3015 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat)
3016         : m_compressedTexture(srcFormat, width, height, depth)
3017 {
3018         de::Random                      random                                  (123);
3019
3020         const int                       compressedDataSize              (m_compressedTexture.getDataSize());
3021         deUint8*                        compressedData                  ((deUint8*)m_compressedTexture.getData());
3022
3023         tcu::TextureFormat      decompressedSrcFormat   (tcu::getUncompressedFormat(srcFormat));
3024         const int                       decompressedDataSize    (tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3025
3026         // generate random data for compresed textre
3027         if (tcu::isAstcFormat(srcFormat))
3028         {
3029                 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3030                 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3031                                                                                          srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3032         }
3033         else if ((dstFormat == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
3034                         ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3035                          (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)))
3036         {
3037                 // special case - when we are blitting compressed image to RGB999E5 image we can't have both big and small values
3038                 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3039                 // blocks that after decompression will have components in proper range
3040
3041                 struct BC6HBlock
3042                 {
3043                         deUint32 data[4];
3044                 };
3045                 std::vector<BC6HBlock> validBlocks;
3046
3047                 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3048                 {
3049                         // define set of few valid blocks that contain values from <0; 1> range
3050                         validBlocks =
3051                         {
3052                                 { 1686671500, 3957317723, 3010132342, 2420137890 },
3053                                 { 3538027716, 298848033, 1925786021, 2022072301 },
3054                                 { 2614043466, 1636155440, 1023731774, 1894349986 },
3055                                 { 3433039318, 1294346072, 1587319645, 1738449906 },
3056                                 { 1386298160, 1639492154, 1273285776, 361562050 },
3057                                 { 1310110688, 526460754, 3630858047, 537617591 },
3058                                 { 3270356556, 2432993217, 2415924417, 1792488857 },
3059                                 { 1204947583, 353249154, 3739153467, 2068076443 },
3060                         };
3061                 }
3062                 else
3063                 {
3064                         // define set of few valid blocks that contain values from <-1; 1> range
3065                         validBlocks =
3066                         {
3067                                 { 2120678840, 3264271120, 4065378848, 3479743703 },
3068                                 { 1479697556, 3480872527, 3369382558, 568252340 },
3069                                 { 1301480032, 1607738094, 3055221704, 3663953681 },
3070                                 { 3531657186, 2285472028, 1429601507, 1969308187 },
3071                                 { 73229044, 650504649, 1120954865, 2626631975 },
3072                                 { 3872486086, 15326178, 2565171269, 2857722432 },
3073                                 { 1301480032, 1607738094, 3055221704, 3663953681 },
3074                                 { 73229044, 650504649, 1120954865, 2626631975 },
3075                         };
3076                 }
3077
3078                 deUint32*       compressedDataUint32    = reinterpret_cast<deUint32*>(compressedData);
3079                 const int       blocksCount                             = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3080
3081                 // fill data using randomly selected valid blocks
3082                 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3083                 {
3084                         deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3085                         deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3086                         compressedDataUint32 += 4;
3087                 }
3088         }
3089         else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3090         {
3091                 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3092                 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3093                         compressedData[byteNdx] = 0xFF & random.getUint32();
3094         }
3095
3096         // alocate space for decompressed texture
3097         m_decompressedData.setStorage(decompressedDataSize);
3098         m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3099
3100         // store decompressed data
3101         m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3102 }
3103
3104 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3105 {
3106         return m_decompressedAccess;
3107 }
3108
3109 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3110 {
3111         return m_compressedTexture;
3112 }
3113
3114 // Copy from image to image with scaling.
3115
3116 class BlittingImages : public CopiesAndBlittingTestInstance
3117 {
3118 public:
3119                                                                                         BlittingImages                                  (Context&       context,
3120                                                                                                                                                          TestParams params);
3121         virtual tcu::TestStatus                                 iterate                                                 (void);
3122 protected:
3123         virtual tcu::TestStatus                                 checkTestResult                                                 (tcu::ConstPixelBufferAccess    result);
3124         virtual void                                                    copyRegionToTextureLevel                                (tcu::ConstPixelBufferAccess    src,
3125                                                                                                                                                                          tcu::PixelBufferAccess                 dst,
3126                                                                                                                                                                          CopyRegion                                             region,
3127                                                                                                                                                                          deUint32                                               mipLevel = 0u);
3128         virtual void                                                    generateExpectedResult                                  (void);
3129         void                                                                    uploadCompressedImage                                   (const VkImage& image, const ImageParms& parms);
3130 private:
3131         bool                                                                    checkNonNearestFilteredResult                   (const tcu::ConstPixelBufferAccess&     result,
3132                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3133                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3134                                                                                                                                                                          const tcu::TextureFormat&                      sourceFormat);
3135         bool                                                                    checkNearestFilteredResult                              (const tcu::ConstPixelBufferAccess&     result,
3136                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     source);
3137
3138         bool                                                                    checkCompressedNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
3139                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3140                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3141                                                                                                                                                                          const tcu::CompressedTexFormat         format);
3142         bool                                                                    checkCompressedNearestFilteredResult    (const tcu::ConstPixelBufferAccess&     result,
3143                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     source,
3144                                                                                                                                                                          const tcu::CompressedTexFormat         format);
3145
3146
3147         Move<VkImage>                                           m_source;
3148         de::MovePtr<Allocation>                         m_sourceImageAlloc;
3149         Move<VkImage>                                           m_destination;
3150         de::MovePtr<Allocation>                         m_destinationImageAlloc;
3151
3152         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel;
3153
3154         // helper used only when bliting from compressed formats
3155         typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3156         CompressedTextureForBlitSp                      m_sourceCompressedTexture;
3157         CompressedTextureForBlitSp                      m_destinationCompressedTexture;
3158 };
3159
3160 BlittingImages::BlittingImages (Context& context, TestParams params)
3161         : CopiesAndBlittingTestInstance(context, params)
3162 {
3163         const InstanceInterface&        vki                                     = context.getInstanceInterface();
3164         const DeviceInterface&          vk                                      = context.getDeviceInterface();
3165         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
3166         const VkDevice                          vkDevice                        = context.getDevice();
3167         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
3168         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
3169
3170         // Create source image
3171         {
3172                 const VkImageCreateInfo         sourceImageParams               =
3173                 {
3174                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3175                         DE_NULL,                                                                // const void*                  pNext;
3176                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
3177                         m_params.src.image.imageType,                   // VkImageType                  imageType;
3178                         m_params.src.image.format,                              // VkFormat                             format;
3179                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
3180                         1u,                                                                             // deUint32                             mipLevels;
3181                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
3182                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3183                         m_params.src.image.tiling,                              // VkImageTiling                tiling;
3184                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3185                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3186                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3187                         1u,                                                                             // deUint32                             queueFamilyCount;
3188                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3189                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3190                 };
3191
3192                 m_source = createImage(vk, vkDevice, &sourceImageParams);
3193                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3194                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3195         }
3196
3197         // Create destination image
3198         {
3199                 const VkImageCreateInfo         destinationImageParams  =
3200                 {
3201                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3202                         DE_NULL,                                                                // const void*                  pNext;
3203                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
3204                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
3205                         m_params.dst.image.format,                              // VkFormat                             format;
3206                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
3207                         1u,                                                                             // deUint32                             mipLevels;
3208                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
3209                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3210                         m_params.dst.image.tiling,                              // VkImageTiling                tiling;
3211                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3212                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3213                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3214                         1u,                                                                             // deUint32                             queueFamilyCount;
3215                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3216                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3217                 };
3218
3219                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3220                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3221                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3222         }
3223 }
3224
3225 tcu::TestStatus BlittingImages::iterate (void)
3226 {
3227         const DeviceInterface&          vk                              = m_context.getDeviceInterface();
3228         const VkDevice                          vkDevice                = m_context.getDevice();
3229         const VkQueue                           queue                   = m_context.getUniversalQueue();
3230
3231         const ImageParms&                       srcImageParams  = m_params.src.image;
3232         const int                                       srcWidth                = static_cast<int>(srcImageParams.extent.width);
3233         const int                                       srcHeight               = static_cast<int>(srcImageParams.extent.height);
3234         const int                                       srcDepth                = static_cast<int>(srcImageParams.extent.depth);
3235         const ImageParms&                       dstImageParams  = m_params.dst.image;
3236         const int                                       dstWidth                = static_cast<int>(dstImageParams.extent.width);
3237         const int                                       dstHeight               = static_cast<int>(dstImageParams.extent.height);
3238         const int                                       dstDepth                = static_cast<int>(dstImageParams.extent.depth);
3239
3240         std::vector<VkImageBlit>                regions;
3241         std::vector<VkImageBlit2KHR>    regions2KHR;
3242
3243         // setup blit regions - they are also needed for reference generation
3244         if (m_params.extensionUse == EXTENSION_USE_NONE)
3245         {
3246                 regions.reserve(m_params.regions.size());
3247                 for (const auto& r : m_params.regions)
3248                         regions.push_back(r.imageBlit);
3249         }
3250         else
3251         {
3252                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3253                 regions2KHR.reserve(m_params.regions.size());
3254                 for (const auto& r : m_params.regions)
3255                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3256         }
3257
3258         // generate source image
3259         if (isCompressedFormat(srcImageParams.format))
3260         {
3261                 // for compressed images srcImageParams.fillMode is not used - we are using random data
3262                 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3263                 m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, dstImageParams.format));
3264                 uploadCompressedImage(m_source.get(), srcImageParams);
3265         }
3266         else
3267         {
3268                 // non-compressed image is filled with selected fillMode
3269                 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3270                 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3271                 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3272                 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3273         }
3274
3275         // generate destination image
3276         if (isCompressedFormat(dstImageParams.format))
3277         {
3278                 // compressed images are filled with random data
3279                 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3280                 m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, VK_FORMAT_UNDEFINED));
3281                 uploadCompressedImage(m_destination.get(), dstImageParams);
3282         }
3283         else
3284         {
3285                 // non-compressed image is filled with white background
3286                 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3287                 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3288                 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3289                 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3290         }
3291
3292         generateExpectedResult();
3293
3294         // Barriers for copying images to buffer
3295         const VkImageMemoryBarrier imageBarriers[]
3296         {
3297                 {
3298                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3299                         DE_NULL,                                                                        // const void*                          pNext;
3300                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3301                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3302                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3303                         srcImageParams.operationLayout,                         // VkImageLayout                        newLayout;
3304                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3305                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3306                         m_source.get(),                                                         // VkImage                                      image;
3307                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3308                                 getAspectFlags(srcImageParams.format),  //   VkImageAspectFlags         aspectMask;
3309                                 0u,                                                                             //   deUint32                           baseMipLevel;
3310                                 1u,                                                                             //   deUint32                           mipLevels;
3311                                 0u,                                                                             //   deUint32                           baseArraySlice;
3312                                 1u                                                                              //   deUint32                           arraySize;
3313                         }
3314                 },
3315                 {
3316                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3317                         DE_NULL,                                                                        // const void*                          pNext;
3318                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3319                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3320                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3321                         dstImageParams.operationLayout,                         // VkImageLayout                        newLayout;
3322                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3323                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3324                         m_destination.get(),                                            // VkImage                                      image;
3325                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3326                                 getAspectFlags(dstImageParams.format),  //   VkImageAspectFlags         aspectMask;
3327                                 0u,                                                                             //   deUint32                           baseMipLevel;
3328                                 1u,                                                                             //   deUint32                           mipLevels;
3329                                 0u,                                                                             //   deUint32                           baseArraySlice;
3330                                 1u                                                                              //   deUint32                           arraySize;
3331                         }
3332                 }
3333         };
3334
3335         beginCommandBuffer(vk, *m_cmdBuffer);
3336         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, 2, imageBarriers);
3337
3338         if (m_params.extensionUse == EXTENSION_USE_NONE)
3339         {
3340                 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
3341         }
3342         else
3343         {
3344                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3345                 const VkBlitImageInfo2KHR blitImageInfo2KHR
3346                 {
3347                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
3348                         DE_NULL,                                                                        // const void*                                  pNext;
3349                         m_source.get(),                                                         // VkImage                                              srcImage;
3350                         srcImageParams.operationLayout,                         // VkImageLayout                                srcImageLayout;
3351                         m_destination.get(),                                            // VkImage                                              dstImage;
3352                         dstImageParams.operationLayout,                         // VkImageLayout                                dstImageLayout;
3353                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
3354                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
3355                         m_params.filter,                                                        // VkFilter                                             filter;
3356                 };
3357                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &blitImageInfo2KHR);
3358         }
3359
3360         endCommandBuffer(vk, *m_cmdBuffer);
3361         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3362
3363         de::MovePtr<tcu::TextureLevel>  resultLevel             = readImage(*m_destination, dstImageParams);
3364         tcu::PixelBufferAccess                  resultAccess    = resultLevel->getAccess();
3365
3366         // if blit was done to a compressed format we need to decompress it to be able to verify it
3367         if (m_destinationCompressedTexture)
3368         {
3369                 deUint8* const                                  compressedDataSrc       (static_cast<deUint8*>(resultAccess.getDataPtr()));
3370                 const tcu::CompressedTexFormat  dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3371                 tcu::TextureLevel                               decompressedLevel       (getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3372                 tcu::PixelBufferAccess                  decompressedAccess      (decompressedLevel.getAccess());
3373
3374                 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3375
3376                 return checkTestResult(decompressedAccess);
3377         }
3378
3379         return checkTestResult(resultAccess);
3380 }
3381
3382 static float calculateFloatConversionError (int srcBits)
3383 {
3384         if (srcBits > 0)
3385         {
3386                 const int       clampedBits     = de::clamp<int>(srcBits, 0, 32);
3387                 const float     srcMaxValue     = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3388                 const float     error           = 1.0f / srcMaxValue;
3389
3390                 return de::clamp<float>(error, 0.0f, 1.0f);
3391         }
3392         else
3393                 return 1.0f;
3394 }
3395
3396 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3397 {
3398         tcu::Vec4 threshold(0.01f);
3399
3400         switch (format.type)
3401         {
3402         case tcu::TextureFormat::HALF_FLOAT:
3403                 threshold = tcu::Vec4(0.005f);
3404                 break;
3405
3406         case tcu::TextureFormat::FLOAT:
3407         case tcu::TextureFormat::FLOAT64:
3408                 threshold = tcu::Vec4(0.001f);
3409                 break;
3410
3411         case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3412                 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3413                 break;
3414
3415         case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3416                 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3417                 break;
3418
3419         case tcu::TextureFormat::UNORM_INT_1010102_REV:
3420                 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3421                 break;
3422
3423         case tcu:: TextureFormat::UNORM_INT8:
3424                 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3425                 break;
3426
3427         default:
3428                 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3429                 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3430                                       calculateFloatConversionError(bits.y()),
3431                                       calculateFloatConversionError(bits.z()),
3432                                       calculateFloatConversionError(bits.w()));
3433         }
3434
3435         // Return value matching the channel order specified by the format
3436         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3437                 return threshold.swizzle(2, 1, 0, 3);
3438         else
3439                 return threshold;
3440 }
3441
3442 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3443 {
3444         bool            isSigned(false);
3445         tcu::IVec4      bitDepth(0);
3446
3447         switch (format)
3448         {
3449         case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3450                 bitDepth = { 7, 0, 0, 0 };
3451                 isSigned = true;
3452                 break;
3453
3454         case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3455                 bitDepth = { 8, 0, 0, 0 };
3456                 break;
3457
3458         case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3459                 bitDepth = { 7, 7, 0, 0 };
3460                 isSigned = true;
3461                 break;
3462
3463         case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3464                 bitDepth = { 8, 8, 0, 0 };
3465                 break;
3466
3467         case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3468         case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3469         case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3470                 bitDepth = { 8, 8, 8, 0 };
3471                 break;
3472
3473         case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3474         case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3475                 bitDepth = { 8, 8, 8, 1 };
3476                 break;
3477
3478         case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3479         case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3480                 bitDepth = { 8, 8, 8, 8 };
3481                 break;
3482
3483         case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3484         case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3485         case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3486         case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3487         case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3488         case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3489                 bitDepth = { 5, 6, 5, 0 };
3490                 break;
3491
3492         case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3493         case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3494         case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3495         case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3496                 bitDepth = { 5, 5, 5, 1 };
3497                 break;
3498
3499         case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3500                 bitDepth = { 7, 0, 0, 0 };
3501                 isSigned = true;
3502                 break;
3503
3504         case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3505                 bitDepth = { 8, 0, 0, 0 };
3506                 break;
3507
3508         case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3509                 bitDepth = { 7, 7, 0, 0 };
3510                 isSigned = true;
3511                 break;
3512
3513         case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3514                 bitDepth = { 8, 8, 0, 0 };
3515                 break;
3516
3517         case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3518                 return tcu::Vec4(0.01f);
3519         case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3520                 return tcu::Vec4(0.005f);
3521
3522         default:
3523                 DE_ASSERT(DE_FALSE);
3524         }
3525
3526         const float     range = isSigned ? 1.0f - (-1.0f)
3527                                                                  : 1.0f - 0.0f;
3528         tcu::Vec4 v;
3529         for (int i = 0; i < 4; ++i)
3530         {
3531                 if (bitDepth[i] == 0)
3532                         v[i] = 1.0f;
3533                 else
3534                         v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3535         }
3536         return v;
3537 }
3538
3539 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&  result,
3540                                                                                                         const tcu::ConstPixelBufferAccess&      clampedExpected,
3541                                                                                                         const tcu::ConstPixelBufferAccess&      unclampedExpected,
3542                                                                                                         const tcu::TextureFormat&                       srcFormat)
3543 {
3544         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
3545         const tcu::TextureFormat                dstFormat               = result.getFormat();
3546         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3547         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3548         bool                                                    isOk                    = false;
3549
3550         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3551
3552         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3553         // the other must also store values a signed/unsigned integer
3554         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3555         // despite the fact that both formats are sampled as floats
3556         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3557                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3558         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3559                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3560         if (dstImageIsIntClass != srcImageIsIntClass)
3561         {
3562                 log << tcu::TestLog::EndSection;
3563                 return false;
3564         }
3565
3566         if (isFloatFormat(dstFormat))
3567         {
3568                 const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
3569                 const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3570                 const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
3571                 const tcu::Vec4 threshold       = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3572
3573                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3574                 log << tcu::TestLog::EndSection;
3575
3576                 if (!isOk)
3577                 {
3578                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3579                         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3580                         log << tcu::TestLog::EndSection;
3581                 }
3582         }
3583         else
3584         {
3585                 tcu::UVec4      threshold;
3586                 // Calculate threshold depending on channel width of destination format.
3587                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
3588                 const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3589                 for (deUint32 i = 0; i < 4; ++i)
3590                         threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3591
3592                 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3593                 log << tcu::TestLog::EndSection;
3594
3595                 if (!isOk)
3596                 {
3597                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3598                         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3599                         log << tcu::TestLog::EndSection;
3600                 }
3601         }
3602
3603         return isOk;
3604 }
3605
3606 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess& result,
3607                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3608                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3609                                                                                                                          const tcu::CompressedTexFormat         format)
3610 {
3611         tcu::TestLog&                           log                     = m_context.getTestContext().getLog();
3612         const tcu::TextureFormat        dstFormat       = result.getFormat();
3613
3614         // there are rare cases wher one or few pixels have slightly bigger error
3615         // in one of channels this accepted error allows those casses to pass
3616         const tcu::Vec4                         acceptedError(0.04f);
3617
3618         const tcu::Vec4                         srcMaxDiff      = getCompressedFormatThreshold(format);
3619         const tcu::Vec4                         dstMaxDiff      = m_destinationCompressedTexture ?
3620                                                                                                 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3621                                                                                                 getFormatThreshold(dstFormat);
3622         const tcu::Vec4                         threshold       = (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3623
3624         bool                                            filteredResultVerification(false);
3625         tcu::Vec4                                       filteredResultMinValue(-6e6);
3626         tcu::Vec4                                       filteredResultMaxValue(6e6);
3627         tcu::TextureLevel                       filteredResult;
3628         tcu::TextureLevel                       filteredClampedReference;
3629         tcu::TextureLevel                       filteredUnclampedReference;
3630
3631         if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3632                 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3633         {
3634                 if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3635                         (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3636                 {
3637                         // for compressed formats we are using random data and for bc6h formats
3638                         // this will give us also large color values; when we are bliting to
3639                         // a format that accepts large values we can end up with large diferences
3640                         // betwean filtered result and reference; to avoid that we need to remove
3641                         // values that are to big from verification
3642                         filteredResultVerification      = true;
3643                         filteredResultMinValue          = tcu::Vec4(-10.0f);
3644                         filteredResultMaxValue          = tcu::Vec4( 10.0f);
3645                 }
3646                 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3647                 {
3648                         // we need to clamp some formats to <0;1> range as it has
3649                         // small precision for big numbers compared to reference
3650                         filteredResultVerification      = true;
3651                         filteredResultMinValue          = tcu::Vec4(0.0f);
3652                         filteredResultMaxValue          = tcu::Vec4(1.0f);
3653                 }
3654                 // else don't use filtered verification
3655         }
3656
3657         if (filteredResultVerification)
3658         {
3659                 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3660                 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3661
3662                 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3663                 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3664
3665                 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3666                 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3667
3668                 for (deInt32 z = 0; z < result.getDepth(); z++)
3669                 for (deInt32 y = 0; y < result.getHeight(); y++)
3670                 for (deInt32 x = 0; x < result.getWidth(); x++)
3671                 {
3672                         tcu::Vec4 resultTexel                           = result.getPixel(x, y, z);
3673                         tcu::Vec4 clampedReferenceTexel         = clampedReference.getPixel(x, y, z);
3674                         tcu::Vec4 unclampedReferenceTexel       = unclampedReference.getPixel(x, y, z);
3675
3676                         resultTexel                             = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3677                         clampedReferenceTexel   = tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3678                         unclampedReferenceTexel = tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3679
3680                         filteredResultAcccess.setPixel(resultTexel, x, y, z);
3681                         filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3682                         filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3683                 }
3684         }
3685
3686         const tcu::ConstPixelBufferAccess clampedRef    = filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3687         const tcu::ConstPixelBufferAccess res                   = filteredResultVerification ? filteredResult.getAccess() : result;
3688
3689         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3690         bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3691         log << tcu::TestLog::EndSection;
3692
3693         if (!isOk)
3694         {
3695                 const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3696
3697                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3698                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3699                 log << tcu::TestLog::EndSection;
3700         }
3701
3702         return isOk;
3703 }
3704
3705 //! Utility to encapsulate coordinate computation and loops.
3706 struct CompareEachPixelInEachRegion
3707 {
3708         virtual          ~CompareEachPixelInEachRegion  (void) {}
3709         virtual bool compare                                                            (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3710
3711         bool forEach (const void*                                                       pUserData,
3712                                   const std::vector<CopyRegion>&                regions,
3713                                   const int                                                             sourceWidth,
3714                                   const int                                                             sourceHeight,
3715                                   const int                                                             sourceDepth,
3716                                   const tcu::PixelBufferAccess&                 errorMask) const
3717         {
3718                 bool compareOk = true;
3719
3720                 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3721                 {
3722                         const VkImageBlit& blit = regionIter->imageBlit;
3723
3724                         const int       xStart  = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3725                         const int       yStart  = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3726                         const int       zStart  = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3727                         const int       xEnd    = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3728                         const int       yEnd    = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3729                         const int       zEnd    = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3730                         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);
3731                         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);
3732                         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);
3733                         const float srcInvW     = 1.0f / static_cast<float>(sourceWidth);
3734                         const float srcInvH     = 1.0f / static_cast<float>(sourceHeight);
3735                         const float srcInvD     = 1.0f / static_cast<float>(sourceDepth);
3736
3737                         for (int z = zStart; z < zEnd; z++)
3738                         for (int y = yStart; y < yEnd; y++)
3739                         for (int x = xStart; x < xEnd; x++)
3740                         {
3741                                 const tcu::Vec3 srcNormCoord
3742                                 (
3743                                         (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3744                                         (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3745                                         (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3746                                 );
3747
3748                                 if (!compare(pUserData, x, y, z, srcNormCoord))
3749                                 {
3750                                         errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3751                                         compareOk = false;
3752                                 }
3753                         }
3754                 }
3755                 return compareOk;
3756         }
3757 };
3758
3759 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3760 {
3761         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
3762         const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
3763
3764         if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3765         {
3766                 return getFormatThreshold(format);
3767         }
3768         else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3769                          channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3770         {
3771                 const bool      isSigned        = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3772                 const float     range           = isSigned ? 1.0f - (-1.0f)
3773                                                                                    : 1.0f -   0.0f;
3774
3775                 tcu::Vec4 v;
3776                 for (int i = 0; i < 4; ++i)
3777                 {
3778                         if (bitDepth[i] == 0)
3779                                 v[i] = 1.0f;
3780                         else
3781                                 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3782                 }
3783                 return v;
3784         }
3785         else
3786         {
3787                 DE_ASSERT(0);
3788                 return tcu::Vec4();
3789         }
3790 }
3791
3792 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&        source,
3793                                                           const tcu::ConstPixelBufferAccess&    result,
3794                                                           const tcu::Vec4&                                              sourceThreshold,
3795                                                           const tcu::Vec4&                                              resultThreshold,
3796                                                           const tcu::PixelBufferAccess&                 errorMask,
3797                                                           const std::vector<CopyRegion>&                regions)
3798 {
3799         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);
3800         const tcu::IVec4                dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3801         tcu::LookupPrecision    precision;
3802
3803         precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3804         precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3805
3806         const struct Capture
3807         {
3808                 const tcu::ConstPixelBufferAccess&      source;
3809                 const tcu::ConstPixelBufferAccess&      result;
3810                 const tcu::Sampler&                                     sampler;
3811                 const tcu::LookupPrecision&                     precision;
3812                 const bool                                                      isSRGB;
3813         } capture =
3814         {
3815                 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3816         };
3817
3818         const struct Loop : CompareEachPixelInEachRegion
3819         {
3820                 Loop (void) {}
3821
3822                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3823                 {
3824                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
3825                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
3826                         tcu::Vec4                                               dstColor                        = c.result.getPixel(x, y, z);
3827
3828                         // TexLookupVerifier performs a conversion to linear space, so we have to as well
3829                         if (c.isSRGB)
3830                                 dstColor = tcu::sRGBToLinear(dstColor);
3831
3832                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3833                 }
3834         } loop;
3835
3836         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3837 }
3838
3839 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&  source,
3840                                                         const tcu::ConstPixelBufferAccess&      result,
3841                                                         const tcu::PixelBufferAccess&           errorMask,
3842                                                         const std::vector<CopyRegion>&          regions)
3843 {
3844         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);
3845         tcu::IntLookupPrecision precision;
3846
3847         {
3848                 const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
3849                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
3850
3851                 for (deUint32 i = 0; i < 4; ++i) {
3852                         precision.colorThreshold[i]     = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3853                         precision.colorMask[i]          = dstBitDepth[i] != 0;
3854                 }
3855         }
3856
3857         // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3858         // does the conversion on the fly without wasting memory, but this approach is more straightforward.
3859         tcu::TextureLevel                               convertedSourceTexture  (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3860         const tcu::PixelBufferAccess    convertedSource                 = convertedSourceTexture.getAccess();
3861
3862         for (int z = 0; z < source.getDepth();  ++z)
3863         for (int y = 0; y < source.getHeight(); ++y)
3864         for (int x = 0; x < source.getWidth();  ++x)
3865                 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3866
3867         const struct Capture
3868         {
3869                 const tcu::ConstPixelBufferAccess&      source;
3870                 const tcu::ConstPixelBufferAccess&      result;
3871                 const tcu::Sampler&                                     sampler;
3872                 const tcu::IntLookupPrecision&          precision;
3873         } capture =
3874         {
3875                 convertedSource, result, sampler, precision
3876         };
3877
3878         const struct Loop : CompareEachPixelInEachRegion
3879         {
3880                 Loop (void) {}
3881
3882                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3883                 {
3884                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
3885                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
3886                         const tcu::IVec4                                dstColor                        = c.result.getPixelInt(x, y, z);
3887
3888                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3889                 }
3890         } loop;
3891
3892         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3893 }
3894
3895 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
3896                                                                                                  const tcu::ConstPixelBufferAccess& source)
3897 {
3898         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
3899         const tcu::TextureFormat                dstFormat               = result.getFormat();
3900         const tcu::TextureFormat                srcFormat               = source.getFormat();
3901         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3902         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3903
3904         tcu::TextureLevel               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3905         tcu::PixelBufferAccess  errorMask                       = errorMaskStorage.getAccess();
3906         tcu::Vec4                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3907         tcu::Vec4                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3908         bool                                    ok                                      = false;
3909
3910         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3911
3912         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3913         // the other must also store values a signed/unsigned integer
3914         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3915         // despite the fact that both formats are sampled as floats
3916         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3917                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3918         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3919                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3920         if (dstImageIsIntClass != srcImageIsIntClass)
3921                 return false;
3922
3923         if (dstImageIsIntClass)
3924         {
3925                 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3926         }
3927         else
3928         {
3929                 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3930                 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
3931                 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
3932         }
3933
3934         if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3935                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3936
3937         if (!ok)
3938         {
3939                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3940                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3941                         << tcu::TestLog::Image("ErrorMask",     "Error mask", errorMask)
3942                         << tcu::TestLog::EndImageSet;
3943         }
3944         else
3945         {
3946                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3947                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3948                         << tcu::TestLog::EndImageSet;
3949         }
3950
3951         return ok;
3952 }
3953
3954 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess&   result,
3955                                                                                                                    const tcu::ConstPixelBufferAccess&   source,
3956                                                                                                                    const tcu::CompressedTexFormat               format)
3957 {
3958         tcu::TestLog&                           log                                     (m_context.getTestContext().getLog());
3959         tcu::TextureFormat                      errorMaskFormat         (tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
3960         tcu::TextureLevel                       errorMaskStorage        (errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
3961         tcu::PixelBufferAccess          errorMask                       (errorMaskStorage.getAccess());
3962         tcu::Vec4                                       pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3963         tcu::Vec4                                       pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3964         const tcu::TextureFormat&       resultFormat            (result.getFormat());
3965         VkFormat                                        nativeResultFormat      (mapTextureFormat(resultFormat));
3966
3967         // there are rare cases wher one or few pixels have slightly bigger error
3968         // in one of channels this accepted error allows those casses to pass
3969         const tcu::Vec4                         acceptedError           (0.04f);
3970         const tcu::Vec4                         srcMaxDiff                      (acceptedError + getCompressedFormatThreshold(format));
3971         const tcu::Vec4                         dstMaxDiff                      (acceptedError + (m_destinationCompressedTexture ?
3972                                                                                                                 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3973                                                                                                                 getFloatOrFixedPointFormatThreshold(resultFormat)));
3974
3975         tcu::TextureLevel                       clampedSourceLevel;
3976         bool                                            clampSource                     (false);
3977         tcu::Vec4                                       clampSourceMinValue     (-1.0f);
3978         tcu::Vec4                                       clampSourceMaxValue     (1.0f);
3979         tcu::TextureLevel                       clampedResultLevel;
3980         bool                                            clampResult                     (false);
3981
3982         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3983
3984         if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3985                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3986
3987         log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3988                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
3989
3990         // for compressed formats source buffer access is not actual compressed format
3991         // but equivalent uncompressed format that is some cases needs additional
3992         // modifications so that sampling it will produce valid reference
3993         if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3994                 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
3995         {
3996                 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3997                 {
3998                         // for compressed formats we are using random data and for some formats it
3999                         // can be outside of <-1;1> range - for cases where result is not a float
4000                         // format we need to clamp source to <-1;1> range as this will be done on
4001                         // the device but not in software sampler in framework
4002                         clampSource = true;
4003                         // for this format we also need to clamp the result as precision of
4004                         // this format is smaller then precision of calculations in framework;
4005                         // the biger color valus are the bigger errors can be
4006                         clampResult = true;
4007
4008                         if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4009                                 clampSourceMinValue = tcu::Vec4(0.0f);
4010                 }
4011                 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4012                                  (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4013                 {
4014                         // clamp source for all non float formats
4015                         clampSource = true;
4016                 }
4017         }
4018
4019         if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4020         {
4021                 // when tested compressed format is signed but the result format
4022                 // is unsigned we need to clamp source to <0; x> so that proper
4023                 // reference is calculated
4024                 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4025                         (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4026                         (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4027                         (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4028                         (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4029                 {
4030                         clampSource                     = true;
4031                         clampSourceMinValue     = tcu::Vec4(0.0f);
4032                 }
4033         }
4034
4035         if (clampSource || clampResult)
4036         {
4037                 if (clampSource)
4038                 {
4039                         clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4040                         tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4041
4042                         for (deInt32 z = 0; z < source.getDepth() ; z++)
4043                         for (deInt32 y = 0; y < source.getHeight() ; y++)
4044                         for (deInt32 x = 0; x < source.getWidth() ; x++)
4045                         {
4046                                 tcu::Vec4 texel = source.getPixel(x, y, z);
4047                                 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4048                                 clampedSourceAcccess.setPixel(texel, x, y, z);
4049                         }
4050                 }
4051
4052                 if (clampResult)
4053                 {
4054                         clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4055                         tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4056
4057                         for (deInt32 z = 0; z < result.getDepth() ; z++)
4058                         for (deInt32 y = 0; y < result.getHeight() ; y++)
4059                         for (deInt32 x = 0; x < result.getWidth() ; x++)
4060                         {
4061                                 tcu::Vec4 texel = result.getPixel(x, y, z);
4062                                 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4063                                 clampedResultAcccess.setPixel(texel, x, y, z);
4064                         }
4065                 }
4066         }
4067
4068         const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4069         const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4070
4071         if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4072         {
4073                 log << tcu::TestLog::EndImageSet;
4074                 return true;
4075         }
4076
4077         log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4078                 << tcu::TestLog::EndImageSet;
4079         return false;
4080 }
4081
4082 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4083 {
4084         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4085         const std::string failMessage("Result image is incorrect");
4086
4087         if (m_params.filter != VK_FILTER_NEAREST)
4088         {
4089                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4090                 {
4091                         if (tcu::hasDepthComponent(result.getFormat().order))
4092                         {
4093                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
4094                                 const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
4095                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4096                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4097                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4098
4099                                 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4100                                         return tcu::TestStatus::fail(failMessage);
4101                         }
4102
4103                         if (tcu::hasStencilComponent(result.getFormat().order))
4104                         {
4105                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
4106                                 const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
4107                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4108                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4109                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4110
4111                                 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4112                                         return tcu::TestStatus::fail(failMessage);
4113                         }
4114                 }
4115                 else if (m_sourceCompressedTexture)
4116                 {
4117                         const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4118                         if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4119                                 return tcu::TestStatus::fail(failMessage);
4120                 }
4121                 else
4122                 {
4123                         const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4124                         if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4125                                 return tcu::TestStatus::fail(failMessage);
4126                 }
4127         }
4128         else // NEAREST filtering
4129         {
4130                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4131                 {
4132                         if (tcu::hasDepthComponent(result.getFormat().order))
4133                         {
4134                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_DEPTH;
4135                                 const tcu::ConstPixelBufferAccess               depthResult             = tcu::getEffectiveDepthStencilAccess(result, mode);
4136                                 const tcu::ConstPixelBufferAccess               depthSource             = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4137
4138                                 if (!checkNearestFilteredResult(depthResult, depthSource))
4139                                         return tcu::TestStatus::fail(failMessage);
4140                         }
4141
4142                         if (tcu::hasStencilComponent(result.getFormat().order))
4143                         {
4144                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_STENCIL;
4145                                 const tcu::ConstPixelBufferAccess               stencilResult   = tcu::getEffectiveDepthStencilAccess(result, mode);
4146                                 const tcu::ConstPixelBufferAccess               stencilSource   = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4147
4148                                 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4149                                         return tcu::TestStatus::fail(failMessage);
4150                         }
4151                 }
4152                 else if (m_sourceCompressedTexture)
4153                 {
4154                         const tcu::CompressedTexture& compressedLevel   = m_sourceCompressedTexture->getCompressedTexture();
4155                         const tcu::PixelBufferAccess& decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4156
4157                         if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4158                                 return tcu::TestStatus::fail(failMessage);
4159                 }
4160                 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4161                         return tcu::TestStatus::fail(failMessage);
4162         }
4163
4164         return tcu::TestStatus::pass("Pass");
4165 }
4166
4167 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4168 {
4169         return isSRGB(format) ? linearToSRGB(color) : color;
4170 }
4171
4172 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4173 {
4174         DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4175
4176         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4177                                         filter, filter, 0.0f, false);
4178
4179         float sX = (float)regionExtent.x / (float)dst.getWidth();
4180         float sY = (float)regionExtent.y / (float)dst.getHeight();
4181         float sZ = (float)regionExtent.z / (float)dst.getDepth();
4182
4183         for (int z = 0; z < dst.getDepth(); z++)
4184         for (int y = 0; y < dst.getHeight(); y++)
4185         for (int x = 0; x < dst.getWidth(); x++)
4186         {
4187                 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;
4188                 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;
4189                 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;
4190                 if (dst.getDepth() > 1)
4191                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4192                 else
4193                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4194         }
4195 }
4196
4197 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4198 {
4199         DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4200
4201         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4202                         filter, filter, 0.0f, false);
4203
4204         const float sX = (float)src.getWidth() / (float)dst.getWidth();
4205         const float sY = (float)src.getHeight() / (float)dst.getHeight();
4206         const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4207
4208         const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4209         const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4210         const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4211
4212         const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4213         const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4214         const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4215
4216         for (int z = 0; z < dst.getDepth(); ++z)
4217         for (int y = 0; y < dst.getHeight(); ++y)
4218         for (int x = 0; x < dst.getWidth(); ++x)
4219         {
4220                 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);
4221         }
4222 }
4223
4224 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4225 {
4226         const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4227         const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4228         const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4229         const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4230
4231         if (mirrorMode != 0u)
4232         {
4233                 //sourceRegion
4234                 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4235                 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4236                 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4237
4238                 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4239                 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4240                 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4241
4242                 //destinationRegion
4243                 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4244                 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4245                 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4246
4247                 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4248                 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4249                 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4250         }
4251 }
4252
4253 // Mirror X, Y and Z as required by the offset values in the 3 axes.
4254 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4255 {
4256         MirrorMode mode = 0u;
4257
4258         if (from.x > to.x)
4259                 mode |= MIRROR_MODE_X;
4260
4261         if (from.y > to.y)
4262                 mode |= MIRROR_MODE_Y;
4263
4264         if (from.z > to.z)
4265                 mode |= MIRROR_MODE_Z;
4266
4267         return mode;
4268 }
4269
4270 // Mirror the axes that are mirrored either in the source or destination, but not both.
4271 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4272 {
4273         static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4274
4275         const MirrorMode source          = getMirrorMode(s1, s2);
4276         const MirrorMode destination = getMirrorMode(d1, d2);
4277
4278         MirrorMode mode = 0u;
4279
4280         for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4281         {
4282                 const MirrorModeBits bit = kBits[i];
4283                 if ((source & bit) != (destination & bit))
4284                         mode |= bit;
4285         }
4286
4287         return mode;
4288 }
4289
4290 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4291 {
4292         DE_UNREF(mipLevel);
4293
4294         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4295                                                                                                 region.imageBlit.srcOffsets[1],
4296                                                                                                 region.imageBlit.dstOffsets[0],
4297                                                                                                 region.imageBlit.dstOffsets[1]);
4298
4299         flipCoordinates(region, mirrorMode);
4300
4301         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
4302         const VkOffset3D                                        srcExtent               =
4303         {
4304                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4305                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4306                 region.imageBlit.srcOffsets[1].z - srcOffset.z,
4307         };
4308         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
4309         const VkOffset3D                                        dstExtent               =
4310         {
4311                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4312                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4313                 region.imageBlit.dstOffsets[1].z - dstOffset.z,
4314         };
4315
4316         tcu::Sampler::FilterMode                filter;
4317         switch (m_params.filter)
4318         {
4319                 case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
4320                 case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
4321                 case VK_FILTER_NEAREST:
4322                 default:                                        filter = tcu::Sampler::NEAREST;  break;
4323         }
4324
4325         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4326         {
4327                 DE_ASSERT(src.getFormat() == dst.getFormat());
4328
4329                 // Scale depth.
4330                 if (tcu::hasDepthComponent(src.getFormat().order))
4331                 {
4332                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4333                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4334                         tcu::scale(dstSubRegion, srcSubRegion, filter);
4335
4336                         if (filter != tcu::Sampler::NEAREST)
4337                         {
4338                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4339                                 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);
4340                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4341                         }
4342                 }
4343
4344                 // Scale stencil.
4345                 if (tcu::hasStencilComponent(src.getFormat().order))
4346                 {
4347                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4348                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4349                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4350
4351                         if (filter != tcu::Sampler::NEAREST)
4352                         {
4353                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4354                                 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);
4355                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4356                         }
4357                 }
4358         }
4359         else
4360         {
4361                 const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4362                 const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4363                 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4364
4365                 if (filter != tcu::Sampler::NEAREST)
4366                 {
4367                         const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4368                         scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4369                 }
4370         }
4371 }
4372
4373 void BlittingImages::generateExpectedResult (void)
4374 {
4375         const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4376         const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4377
4378         m_expectedTextureLevel[0]               = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4379         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4380
4381         if (m_params.filter != VK_FILTER_NEAREST)
4382         {
4383                 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4384                 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4385         }
4386
4387         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4388         {
4389                 CopyRegion region = m_params.regions[i];
4390                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4391         }
4392 }
4393
4394 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4395 {
4396         DE_ASSERT(m_sourceCompressedTexture);
4397
4398         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
4399         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
4400         const VkPhysicalDevice                  vkPhysDevice            = m_context.getPhysicalDevice();
4401         const VkDevice                                  vkDevice                        = m_context.getDevice();
4402         const VkQueue                                   queue                           = m_context.getUniversalQueue();
4403         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
4404         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
4405         Move<VkBuffer>                                  buffer;
4406         const deUint32                                  bufferSize                      = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4407         de::MovePtr<Allocation>                 bufferAlloc;
4408         const deUint32                                  arraySize                       = getArraySize(parms);
4409         const VkExtent3D                                imageExtent
4410         {
4411                 parms.extent.width,
4412                 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4413                 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4414         };
4415
4416         // Create source buffer
4417         {
4418                 const VkBufferCreateInfo bufferParams
4419                 {
4420                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
4421                         DE_NULL,                                                                        // const void*                  pNext;
4422                         0u,                                                                                     // VkBufferCreateFlags  flags;
4423                         bufferSize,                                                                     // VkDeviceSize                 size;
4424                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
4425                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
4426                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
4427                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
4428                 };
4429
4430                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
4431                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4432                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4433         }
4434
4435         // Barriers for copying buffer to image
4436         const VkBufferMemoryBarrier preBufferBarrier
4437         {
4438                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
4439                 DE_NULL,                                                                                // const void*          pNext;
4440                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
4441                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
4442                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
4443                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
4444                 *buffer,                                                                                // VkBuffer                     buffer;
4445                 0u,                                                                                             // VkDeviceSize         offset;
4446                 bufferSize                                                                              // VkDeviceSize         size;
4447         };
4448
4449         const VkImageMemoryBarrier preImageBarrier
4450         {
4451                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4452                 DE_NULL,                                                                                // const void*                          pNext;
4453                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
4454                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
4455                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
4456                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
4457                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4458                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4459                 image,                                                                                  // VkImage                                      image;
4460                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
4461                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspect;
4462                         0u,                                                     // deUint32                             baseMipLevel;
4463                         1u,                                                     // deUint32                             mipLevels;
4464                         0u,                                                     // deUint32                             baseArraySlice;
4465                         arraySize,                                      // deUint32                             arraySize;
4466                 }
4467         };
4468
4469         const VkImageMemoryBarrier postImageBarrier
4470         {
4471                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4472                 DE_NULL,                                                                                // const void*                          pNext;
4473                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
4474                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
4475                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
4476                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
4477                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4478                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4479                 image,                                                                                  // VkImage                                      image;
4480                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
4481                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspect;
4482                         0u,                                                             // deUint32                             baseMipLevel;
4483                         1u,                                                             // deUint32                             mipLevels;
4484                         0u,                                                             // deUint32                             baseArraySlice;
4485                         arraySize,                                              // deUint32                             arraySize;
4486                 }
4487         };
4488
4489         const VkExtent3D copyExtent
4490         {
4491                 imageExtent.width,
4492                 imageExtent.height,
4493                 imageExtent.depth
4494         };
4495
4496         VkBufferImageCopy copyRegion
4497         {
4498                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
4499                 copyExtent.width,                                                               // deUint32                                     bufferRowLength;
4500                 copyExtent.height,                                                              // deUint32                                     bufferImageHeight;
4501                 {
4502                         VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspect;
4503                         0u,                                                                                             // deUint32                             mipLevel;
4504                         0u,                                                                                             // deUint32                             baseArrayLayer;
4505                         arraySize,                                                                              // deUint32                             layerCount;
4506                 },                                                                                              // VkImageSubresourceLayers     imageSubresource;
4507                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
4508                 copyExtent                                                                              // VkExtent3D                           imageExtent;
4509         };
4510
4511         // Write buffer data
4512         deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4513         flushAlloc(vk, vkDevice, *bufferAlloc);
4514
4515         // Copy buffer to image
4516         beginCommandBuffer(vk, *m_cmdBuffer);
4517         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4518                                                   1, &preBufferBarrier, 1, &preImageBarrier);
4519         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
4520         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);
4521         endCommandBuffer(vk, *m_cmdBuffer);
4522
4523         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4524 }
4525
4526
4527 class BlitImageTestCase : public vkt::TestCase
4528 {
4529 public:
4530                                                         BlitImageTestCase               (tcu::TestContext&                              testCtx,
4531                                                                                                          const std::string&                             name,
4532                                                                                                          const std::string&                             description,
4533                                                                                                          const TestParams                               params)
4534                                                                 : vkt::TestCase (testCtx, name, description)
4535                                                                 , m_params              (params)
4536         {}
4537
4538         virtual TestInstance*   createInstance                  (Context&                                               context) const
4539         {
4540                 return new BlittingImages(context, m_params);
4541         }
4542
4543         virtual void                    checkSupport                    (Context&                                               context) const
4544         {
4545                 VkImageFormatProperties properties;
4546                 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4547                                                                                                                                                                         m_params.src.image.format,
4548                                                                                                                                                                         m_params.src.image.imageType,
4549                                                                                                                                                                         m_params.src.image.tiling,
4550                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4551                                                                                                                                                                         0,
4552                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4553                 {
4554                         TCU_THROW(NotSupportedError, "Source format not supported");
4555                 }
4556                 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4557                                                                                                                                                                         m_params.dst.image.format,
4558                                                                                                                                                                         m_params.dst.image.imageType,
4559                                                                                                                                                                         m_params.dst.image.tiling,
4560                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4561                                                                                                                                                                         0,
4562                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4563                 {
4564                         TCU_THROW(NotSupportedError, "Destination format not supported");
4565                 }
4566
4567                 VkFormatProperties srcFormatProperties;
4568                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4569                 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4570                 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4571                 {
4572                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4573                 }
4574
4575                 VkFormatProperties dstFormatProperties;
4576                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4577                 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4578                 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4579                 {
4580                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4581                 }
4582
4583                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4584                 {
4585                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4586                 }
4587
4588                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4589                 {
4590                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4591
4592                         if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4593                         {
4594                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4595                         }
4596                 }
4597
4598                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4599                 {
4600                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4601                         {
4602                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4603                         }
4604                 }
4605         }
4606
4607 private:
4608         TestParams                              m_params;
4609 };
4610
4611 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4612 {
4613 public:
4614                                                                                 BlittingMipmaps                                 (Context&   context,
4615                                                                                                                                                  TestParams params);
4616         virtual tcu::TestStatus                         iterate                                                 (void);
4617 protected:
4618         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4619         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4620         virtual void                                            generateExpectedResult                  (void);
4621 private:
4622         bool                                                            checkNonNearestFilteredResult   (void);
4623         bool                                                            checkNearestFilteredResult              (void);
4624
4625         Move<VkImage>                                           m_source;
4626         de::MovePtr<Allocation>                         m_sourceImageAlloc;
4627         Move<VkImage>                                           m_destination;
4628         de::MovePtr<Allocation>                         m_destinationImageAlloc;
4629
4630         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel[16];
4631 };
4632
4633 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4634         : CopiesAndBlittingTestInstance (context, params)
4635 {
4636         const InstanceInterface&        vki                                     = context.getInstanceInterface();
4637         const DeviceInterface&          vk                                      = context.getDeviceInterface();
4638         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
4639         const VkDevice                          vkDevice                        = context.getDevice();
4640         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
4641         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
4642
4643         // Create source image
4644         {
4645                 const VkImageCreateInfo         sourceImageParams               =
4646                 {
4647                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
4648                         DE_NULL,                                                                // const void*                  pNext;
4649                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
4650                         m_params.src.image.imageType,                   // VkImageType                  imageType;
4651                         m_params.src.image.format,                              // VkFormat                             format;
4652                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
4653                         1u,                                                                             // deUint32                             mipLevels;
4654                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
4655                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
4656                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
4657                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4658                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
4659                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
4660                         1u,                                                                             // deUint32                             queueFamilyCount;
4661                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
4662                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
4663                 };
4664
4665                 m_source = createImage(vk, vkDevice, &sourceImageParams);
4666                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4667                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4668         }
4669
4670         // Create destination image
4671         {
4672                 const VkImageCreateInfo         destinationImageParams  =
4673                 {
4674                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
4675                         DE_NULL,                                                                // const void*                  pNext;
4676                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
4677                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
4678                         m_params.dst.image.format,                              // VkFormat                             format;
4679                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
4680                         m_params.mipLevels,                                             // deUint32                             mipLevels;
4681                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
4682                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
4683                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
4684                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4685                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
4686                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
4687                         1u,                                                                             // deUint32                             queueFamilyCount;
4688                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
4689                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
4690                 };
4691
4692                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
4693                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4694                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4695         }
4696 }
4697
4698 tcu::TestStatus BlittingMipmaps::iterate (void)
4699 {
4700         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
4701         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
4702         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4703                                                                                                                                                                 m_params.src.image.extent.width,
4704                                                                                                                                                                 m_params.src.image.extent.height,
4705                                                                                                                                                                 m_params.src.image.extent.depth));
4706         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);
4707         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4708                                                                                                                                                                                 (int)m_params.dst.image.extent.width,
4709                                                                                                                                                                                 (int)m_params.dst.image.extent.height,
4710                                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
4711         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);
4712         generateExpectedResult();
4713
4714         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4715
4716         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4717
4718         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
4719         const VkDevice                          vkDevice                        = m_context.getDevice();
4720         const VkQueue                           queue                           = m_context.getUniversalQueue();
4721
4722         std::vector<VkImageBlit>                regions;
4723         std::vector<VkImageBlit2KHR>    regions2KHR;
4724         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4725         {
4726                 if (m_params.extensionUse == EXTENSION_USE_NONE)
4727                 {
4728                         regions.push_back(m_params.regions[i].imageBlit);
4729                 }
4730                 else
4731                 {
4732                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4733                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4734                 }
4735         }
4736
4737         // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4738         if (!m_params.singleCommand)
4739                 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4740
4741         beginCommandBuffer(vk, *m_cmdBuffer);
4742
4743         // Blit all mip levels with a single blit command
4744         if (m_params.singleCommand)
4745         {
4746                 {
4747                         // Source image layout
4748                         const VkImageMemoryBarrier              srcImageBarrier         =
4749                         {
4750                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4751                                 DE_NULL,                                                                        // const void*                          pNext;
4752                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4753                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
4754                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
4755                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
4756                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4757                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4758                                 m_source.get(),                                                         // VkImage                                      image;
4759                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4760                                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
4761                                         0u,                                                                     // deUint32                             baseMipLevel;
4762                                         1u,                                                                     // deUint32                             mipLevels;
4763                                         0u,                                                                     // deUint32                             baseArraySlice;
4764                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
4765                                 }
4766                         };
4767
4768                         // Destination image layout
4769                         const VkImageMemoryBarrier              dstImageBarrier         =
4770                         {
4771                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4772                                 DE_NULL,                                                                        // const void*                          pNext;
4773                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4774                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4775                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
4776                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4777                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4778                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4779                                 m_destination.get(),                                            // VkImage                                      image;
4780                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4781                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4782                                         0u,                                                                     // deUint32                             baseMipLevel;
4783                                         m_params.mipLevels,                                     // deUint32                             mipLevels;
4784                                         0u,                                                                     // deUint32                             baseArraySlice;
4785                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4786                                 }
4787                         };
4788
4789                         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);
4790                         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);
4791
4792                         if (m_params.extensionUse == EXTENSION_USE_NONE)
4793                         {
4794                                 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);
4795                         }
4796                         else
4797                         {
4798                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4799                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4800                                 {
4801                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
4802                                         DE_NULL,                                                                        // const void*                                  pNext;
4803                                         m_source.get(),                                                         // VkImage                                              srcImage;
4804                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
4805                                         m_destination.get(),                                            // VkImage                                              dstImage;
4806                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
4807                                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
4808                                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
4809                                         m_params.filter                                                         // VkFilter                                             filter;
4810                                 };
4811                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4812                         }
4813                 }
4814         }
4815         // Blit mip levels with multiple blit commands
4816         else
4817         {
4818                 // Prepare all mip levels for reading
4819                 {
4820                         for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4821                         {
4822                                 VkImageMemoryBarrier preImageBarrier =
4823                                 {
4824                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType      sType;
4825                                         DE_NULL,                                                                                                                                // const void*          pNext;
4826                                         VK_ACCESS_TRANSFER_WRITE_BIT,                                                                                   // VkAccessFlags        srcAccessMask;
4827                                         VK_ACCESS_TRANSFER_READ_BIT,                                                                                    // VkAccessFlags        dstAccessMask;
4828                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                                                                   // VkImageLayout        oldLayout;
4829                                         m_params.src.image.operationLayout,                                                                             // VkImageLayout        newLayout;
4830                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     srcQueueFamilyIndex;
4831                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     dstQueueFamilyIndex;
4832                                         m_destination.get(),                                                                                                    // VkImage                      image;
4833                                         {                                                                                                                                               // VkImageSubresourceRange      subresourceRange;
4834                                                 getAspectFlags(dstTcuFormat),                                                                           // VkImageAspectFlags   aspectMask;
4835                                                         0u,                                                                                                                             // deUint32                             baseMipLevel;
4836                                                         VK_REMAINING_MIP_LEVELS,                                                                                // deUint32                             mipLevels;
4837                                                         0u,                                                                                                                             // deUint32                             baseArraySlice;
4838                                                         getArraySize(m_params.src.image)                                                                // deUint32                             arraySize;
4839                                         }
4840                                 };
4841
4842                                 if (getArraySize(m_params.src.image) == 1)
4843                                 {
4844                                         DE_ASSERT(barrierno < m_params.mipLevels);
4845                                         preImageBarrier.subresourceRange.baseMipLevel   = barrierno;
4846                                         preImageBarrier.subresourceRange.levelCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4847                                 }
4848                                 else
4849                                 {
4850                                         preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
4851                                         preImageBarrier.subresourceRange.layerCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4852                                 }
4853                                 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);
4854                         }
4855                 }
4856
4857                 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4858                 {
4859                         const deUint32  mipLevel        = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4860
4861                         // Prepare single mip level for writing
4862                         const VkImageMemoryBarrier              preImageBarrier         =
4863                         {
4864                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4865                                 DE_NULL,                                                                        // const void*                                  pNext;
4866                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
4867                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4868                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
4869                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4870                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4871                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4872                                 m_destination.get(),                                            // VkImage                                      image;
4873                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4874                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4875                                         mipLevel,                                                       // deUint32                             baseMipLevel;
4876                                         1u,                                                                     // deUint32                             mipLevels;
4877                                         0u,                                                                     // deUint32                             baseArraySlice;
4878                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4879                                 }
4880                         };
4881
4882                         // Prepare single mip level for reading
4883                         const VkImageMemoryBarrier              postImageBarrier        =
4884                         {
4885                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4886                                 DE_NULL,                                                                        // const void*                          pNext;
4887                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4888                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
4889                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        oldLayout;
4890                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
4891                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4892                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4893                                 m_destination.get(),                                            // VkImage                                      image;
4894                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4895                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4896                                         mipLevel,                                                       // deUint32                             baseMipLevel;
4897                                         1u,                                                                     // deUint32                             mipLevels;
4898                                         0u,                                                                     // deUint32                             baseArraySlice;
4899                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
4900                                 }
4901                         };
4902
4903                         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);
4904
4905                         if (m_params.extensionUse == EXTENSION_USE_NONE)
4906                         {
4907                                 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);
4908                         }
4909                         else
4910                         {
4911                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4912                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4913                                 {
4914                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
4915                                         DE_NULL,                                                                        // const void*                                  pNext;
4916                                         m_destination.get(),                                            // VkImage                                              srcImage;
4917                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
4918                                         m_destination.get(),                                            // VkImage                                              dstImage;
4919                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
4920                                         1u,                                                                                     // uint32_t                                             regionCount;
4921                                         &regions2KHR[regionNdx],                                        // const VkImageBlit2KHR*               pRegions;
4922                                         m_params.filter                                                         // VkFilter                                             filter;
4923                                 };
4924                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4925                         }
4926
4927                         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);
4928                 }
4929
4930                 // Prepare all mip levels for writing
4931                 {
4932                         const VkImageMemoryBarrier              postImageBarrier                =
4933                         {
4934                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4935                                 DE_NULL,                                                                        // const void*                          pNext;
4936                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
4937                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4938                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
4939                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4940                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4941                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4942                                 m_destination.get(),                                            // VkImage                                      image;
4943                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4944                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4945                                         0u,                                                                     // deUint32                             baseMipLevel;
4946                                         VK_REMAINING_MIP_LEVELS,                        // deUint32                             mipLevels;
4947                                         0u,                                                                     // deUint32                             baseArraySlice;
4948                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4949                                 }
4950                         };
4951
4952                         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);
4953                 }
4954         }
4955
4956         endCommandBuffer(vk, *m_cmdBuffer);
4957         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4958
4959         return checkTestResult();
4960 }
4961
4962 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
4963 {
4964         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
4965         bool                                            allLevelsOk             = true;
4966
4967         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4968         {
4969                 // Update reference results with previous results that have been verified.
4970                 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
4971                 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4972                 {
4973                         const CopyRegion region = m_params.regions[i];
4974                         const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
4975                         const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
4976                         de::MovePtr<tcu::TextureLevel>  prevResultLevel;
4977                         tcu::ConstPixelBufferAccess src;
4978                         if (srcMipLevel < mipLevelNdx)
4979                         {
4980                                 // Generate expected result from rendered result that was previously verified
4981                                 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
4982                                 src = prevResultLevel->getAccess();
4983                         }
4984                         else
4985                         {
4986                                 // Previous reference mipmaps might have changed, so recompute expected result
4987                                 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
4988                         }
4989                         copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
4990                 }
4991
4992                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
4993                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
4994
4995                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
4996                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
4997                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
4998                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
4999                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5000                                                                                                                                                                                                                                                                         resultAccess;
5001                 const tcu::ConstPixelBufferAccess               clampedLevel            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5002                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5003                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx]->getAccess();
5004                 const tcu::ConstPixelBufferAccess               unclampedLevel          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5005                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5006                                                                                                                                                                                                                                                                         m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5007                 const tcu::TextureFormat                                srcFormat                       = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5008                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5009                                                                                                                                                                                                                                                                         mapVkFormat(m_params.src.image.format);
5010
5011                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
5012                 bool                                                                    singleLevelOk           = false;
5013                 std::vector <CopyRegion>                                mipLevelRegions;
5014
5015                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5016                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5017                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5018
5019                 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5020
5021                 if (isFloatFormat(dstFormat))
5022                 {
5023                         const bool              srcIsSRGB   = tcu::isSRGB(srcFormat);
5024                         const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5025                         const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
5026                         const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5027
5028                         singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5029                         log << tcu::TestLog::EndSection;
5030
5031                         if (!singleLevelOk)
5032                         {
5033                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5034                                 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5035                                 log << tcu::TestLog::EndSection;
5036                         }
5037                 }
5038                 else
5039                 {
5040                         tcu::UVec4  threshold;
5041                         // Calculate threshold depending on channel width of destination format.
5042                         const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
5043                         const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5044                         for (deUint32 i = 0; i < 4; ++i)
5045                                 threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5046
5047                         singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5048                         log << tcu::TestLog::EndSection;
5049
5050                         if (!singleLevelOk)
5051                         {
5052                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5053                                 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5054                                 log << tcu::TestLog::EndSection;
5055                         }
5056                 }
5057                 allLevelsOk &= singleLevelOk;
5058         }
5059
5060         return allLevelsOk;
5061 }
5062
5063 bool BlittingMipmaps::checkNearestFilteredResult (void)
5064 {
5065         bool                                            allLevelsOk             = true;
5066         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
5067
5068         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5069         {
5070                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5071                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
5072
5073                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
5074                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5075                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
5076                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5077                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5078                                                                                                                                                                                                                                                                         resultAccess;
5079                 const tcu::ConstPixelBufferAccess               source                          = (m_params.singleCommand || mipLevelNdx == 0) ?                        //  Read from source image
5080                                                                                                                                           tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5081                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5082                                                                                                                                                                                                                                                                         m_sourceTextureLevel->getAccess()
5083                                                                                                                                                                                                                                                                 //  Read from destination image
5084                                                                                                                                         : tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5085                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5086                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5087                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
5088                 const tcu::TextureChannelClass                  dstChannelClass         = tcu::getTextureChannelClass(dstFormat.type);
5089                 bool                                                                    singleLevelOk           = false;
5090                 std::vector <CopyRegion>                                mipLevelRegions;
5091
5092                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5093                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5094                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5095
5096                 tcu::TextureLevel                               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5097                 tcu::PixelBufferAccess                  errorMask                       = errorMaskStorage.getAccess();
5098                 tcu::Vec4                                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
5099                 tcu::Vec4                                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
5100
5101                 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5102
5103                 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5104                         dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5105                 {
5106                         singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5107                 }
5108                 else
5109                 {
5110                         const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5111                         const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5112
5113                         singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5114                 }
5115
5116                 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5117                         tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5118
5119                 if (!singleLevelOk)
5120                 {
5121                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5122                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5123                                 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5124                                 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5125                                 << tcu::TestLog::EndImageSet;
5126                 }
5127                 else
5128                 {
5129                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5130                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5131                                 << tcu::TestLog::EndImageSet;
5132                 }
5133
5134                 allLevelsOk &= singleLevelOk;
5135         }
5136
5137         return allLevelsOk;
5138 }
5139
5140 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5141 {
5142         DE_UNREF(result);
5143         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5144         const std::string failMessage("Result image is incorrect");
5145
5146         if (m_params.filter != VK_FILTER_NEAREST)
5147         {
5148                 if (!checkNonNearestFilteredResult())
5149                         return tcu::TestStatus::fail(failMessage);
5150         }
5151         else // NEAREST filtering
5152         {
5153                 if (!checkNearestFilteredResult())
5154                         return tcu::TestStatus::fail(failMessage);
5155         }
5156
5157         return tcu::TestStatus::pass("Pass");
5158 }
5159
5160 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5161 {
5162         DE_ASSERT(src.getDepth() == dst.getDepth());
5163
5164         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5165                                                                                                 region.imageBlit.srcOffsets[1],
5166                                                                                                 region.imageBlit.dstOffsets[0],
5167                                                                                                 region.imageBlit.dstOffsets[1]);
5168
5169         flipCoordinates(region, mirrorMode);
5170
5171         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
5172         const VkOffset3D                                        srcExtent               =
5173         {
5174                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5175                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5176                 region.imageBlit.srcOffsets[1].z - srcOffset.z
5177         };
5178         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
5179         const VkOffset3D                                        dstExtent               =
5180         {
5181                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5182                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5183                 region.imageBlit.dstOffsets[1].z - dstOffset.z
5184         };
5185
5186         tcu::Sampler::FilterMode                filter;
5187         switch (m_params.filter)
5188         {
5189         case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
5190         case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
5191         case VK_FILTER_NEAREST:
5192         default:                                        filter = tcu::Sampler::NEAREST;  break;
5193         }
5194
5195         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5196         {
5197                 DE_ASSERT(src.getFormat() == dst.getFormat());
5198                 // Scale depth.
5199                 if (tcu::hasDepthComponent(src.getFormat().order))
5200                 {
5201                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5202                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5203                         tcu::scale(dstSubRegion, srcSubRegion, filter);
5204
5205                         if (filter != tcu::Sampler::NEAREST)
5206                         {
5207                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5208                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5209                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5210                         }
5211                 }
5212
5213                 // Scale stencil.
5214                 if (tcu::hasStencilComponent(src.getFormat().order))
5215                 {
5216                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5217                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5218                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5219
5220                         if (filter != tcu::Sampler::NEAREST)
5221                         {
5222                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5223                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5224                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5225                         }
5226                 }
5227         }
5228         else
5229         {
5230                 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5231                 {
5232                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5233                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5234                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5235
5236                         if (filter != tcu::Sampler::NEAREST)
5237                         {
5238                                 const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5239                                 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5240                         }
5241                 }
5242         }
5243 }
5244
5245 void BlittingMipmaps::generateExpectedResult (void)
5246 {
5247         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
5248         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
5249
5250         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5251                 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5252
5253         tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5254
5255         if (m_params.filter != VK_FILTER_NEAREST)
5256         {
5257                 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5258                         m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5259
5260                 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5261         }
5262
5263         for (deUint32 i = 0; i < m_params.regions.size(); i++)
5264         {
5265                 CopyRegion region = m_params.regions[i];
5266                 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);
5267         }
5268 }
5269
5270 class BlitMipmapTestCase : public vkt::TestCase
5271 {
5272 public:
5273                                                         BlitMipmapTestCase              (tcu::TestContext&                              testCtx,
5274                                                                                                          const std::string&                             name,
5275                                                                                                          const std::string&                             description,
5276                                                                                                          const TestParams                               params)
5277                                                                 : vkt::TestCase (testCtx, name, description)
5278                                                                 , m_params              (params)
5279         {}
5280
5281         virtual TestInstance*   createInstance                  (Context&                                               context) const
5282         {
5283                 return new BlittingMipmaps(context, m_params);
5284         }
5285
5286         virtual void                    checkSupport                    (Context&                                               context) const
5287         {
5288                 const InstanceInterface&        vki                                     = context.getInstanceInterface();
5289                 const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
5290                 {
5291                         VkImageFormatProperties properties;
5292                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5293                                                                                                                                                                                 m_params.src.image.format,
5294                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
5295                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
5296                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5297                                                                                                                                                                                 0,
5298                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5299                         {
5300                                 TCU_THROW(NotSupportedError, "Format not supported");
5301                         }
5302                         else if ((m_params.src.image.extent.width       > properties.maxExtent.width)   ||
5303                                                 (m_params.src.image.extent.height       > properties.maxExtent.height)  ||
5304                                                 (m_params.src.image.extent.depth        > properties.maxArrayLayers))
5305                         {
5306                                 TCU_THROW(NotSupportedError, "Image size not supported");
5307                         }
5308                 }
5309
5310                 {
5311                         VkImageFormatProperties properties;
5312                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5313                                                                                                                                                                                 m_params.dst.image.format,
5314                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
5315                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
5316                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5317                                                                                                                                                                                 0,
5318                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5319                         {
5320                                 TCU_THROW(NotSupportedError, "Format not supported");
5321                         }
5322                         else if ((m_params.dst.image.extent.width       > properties.maxExtent.width)   ||
5323                                                 (m_params.dst.image.extent.height       > properties.maxExtent.height)  ||
5324                                                 (m_params.dst.image.extent.depth        > properties.maxArrayLayers))
5325                         {
5326                                 TCU_THROW(NotSupportedError, "Image size not supported");
5327                         }
5328                         else if (m_params.mipLevels > properties.maxMipLevels)
5329                         {
5330                                 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5331                         }
5332                         else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)        &&
5333                                          (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5334                         {
5335                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5336                         }
5337                 }
5338
5339                 const VkFormatProperties        srcFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5340                 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5341                 {
5342                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5343                 }
5344
5345                 const VkFormatProperties        dstFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5346                 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5347                 {
5348                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5349                 }
5350
5351                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5352                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5353
5354                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5355                 {
5356                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5357
5358                         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5359                         {
5360                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5361                         }
5362                 }
5363         }
5364
5365 private:
5366         TestParams                              m_params;
5367 };
5368
5369 // Resolve image to image.
5370
5371 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
5372 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5373 {
5374 public:
5375                                                                                                 ResolveImageToImage                     (Context&                                                       context,
5376                                                                                                                                                          TestParams                                                     params,
5377                                                                                                                                                          const ResolveImageToImageOptions       options);
5378         virtual tcu::TestStatus                                         iterate                                         (void);
5379 protected:
5380         virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
5381         void                                                                            copyMSImageToMSImage            (deUint32 copyArraySize);
5382         tcu::TestStatus                                                         checkIntermediateCopy           (void);
5383 private:
5384         Move<VkImage>                                                           m_multisampledImage;
5385         de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
5386
5387         Move<VkImage>                                                           m_destination;
5388         de::MovePtr<Allocation>                                         m_destinationImageAlloc;
5389
5390         Move<VkImage>                                                           m_multisampledCopyImage;
5391         de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
5392
5393         const ResolveImageToImageOptions                        m_options;
5394
5395         virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
5396                                                                                                                                                          tcu::PixelBufferAccess                 dst,
5397                                                                                                                                                          CopyRegion                                             region,
5398                                                                                                                                                          deUint32                                               mipLevel = 0u);
5399 };
5400
5401 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5402         : CopiesAndBlittingTestInstance (context, params)
5403         , m_options                                             (options)
5404 {
5405         const InstanceInterface&        vki                                             = m_context.getInstanceInterface();
5406         const DeviceInterface&          vk                                              = m_context.getDeviceInterface();
5407         const VkPhysicalDevice          vkPhysDevice                    = m_context.getPhysicalDevice();
5408         const VkDevice                          vkDevice                                = m_context.getDevice();
5409         const deUint32                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
5410         Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
5411
5412         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5413         Move<VkRenderPass>                      renderPass;
5414
5415         Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5416         Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5417         std::vector<tcu::Vec4>          vertices;
5418
5419         Move<VkBuffer>                          vertexBuffer;
5420         de::MovePtr<Allocation>         vertexBufferAlloc;
5421
5422         Move<VkPipelineLayout>          pipelineLayout;
5423         Move<VkPipeline>                        graphicsPipeline;
5424
5425         const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
5426
5427         // Create color image.
5428         {
5429                 VkImageCreateInfo       colorImageParams        =
5430                 {
5431                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
5432                         DE_NULL,                                                                                                                                // const void*                          pNext;
5433                         getCreateFlags(m_params.src.image),                                                                             // VkImageCreateFlags           flags;
5434                         m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
5435                         m_params.src.image.format,                                                                                              // VkFormat                                     format;
5436                         getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
5437                         1u,                                                                                                                                             // deUint32                                     mipLevels;
5438                         getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
5439                         rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
5440                         VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
5441                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                                                                             // VkImageUsageFlags            usage;
5442                                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5443                                 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5444                         VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
5445                         1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
5446                         &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
5447                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
5448                 };
5449
5450                 m_multisampledImage                                             = createImage(vk, vkDevice, &colorImageParams);
5451
5452                 // Allocate and bind color image memory.
5453                 m_multisampledImageAlloc                                = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5454                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
5455
5456                 switch (m_options)
5457                 {
5458                         case COPY_MS_IMAGE_TO_MS_IMAGE:
5459                         {
5460                                 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;
5461                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
5462                                 // Allocate and bind color image memory.
5463                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5464                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5465                                 break;
5466                         }
5467
5468                         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5469                         {
5470                                 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;
5471                                 colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
5472                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
5473                                 // Allocate and bind color image memory.
5474                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5475                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5476                                 break;
5477                         }
5478
5479                         default :
5480                                 break;
5481                 }
5482         }
5483
5484         // Create destination image.
5485         {
5486                 const VkImageCreateInfo destinationImageParams  =
5487                 {
5488                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
5489                         DE_NULL,                                                                // const void*                  pNext;
5490                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
5491                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
5492                         m_params.dst.image.format,                              // VkFormat                             format;
5493                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
5494                         1u,                                                                             // deUint32                             mipLevels;
5495                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
5496                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
5497                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
5498                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5499                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
5500                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
5501                         1u,                                                                             // deUint32                             queueFamilyCount;
5502                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
5503                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
5504                 };
5505
5506                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
5507                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5508                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5509         }
5510
5511         // Barriers for copying image to buffer
5512         VkImageMemoryBarrier            srcImageBarrier         =
5513         {
5514                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5515                 DE_NULL,                                                                        // const void*                          pNext;
5516                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
5517                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
5518                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
5519                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
5520                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5521                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5522                 m_multisampledImage.get(),                                      // VkImage                                      image;
5523                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
5524                         VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
5525                         0u,                                                                     // deUint32                             baseMipLevel;
5526                         1u,                                                                     // deUint32                             mipLevels;
5527                         0u,                                                                     // deUint32                             baseArraySlice;
5528                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
5529                 }
5530         };
5531
5532         // Create render pass.
5533         {
5534                 const VkAttachmentDescription   attachmentDescriptions[1]       =
5535                 {
5536                         {
5537                                 0u,                                                                                     // VkAttachmentDescriptionFlags         flags;
5538                                 m_params.src.image.format,                                      // VkFormat                                                     format;
5539                                 rasterizationSamples,                                           // VkSampleCountFlagBits                        samples;
5540                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
5541                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
5542                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
5543                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
5544                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
5545                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
5546                         },
5547                 };
5548
5549                 const VkAttachmentReference             colorAttachmentReference        =
5550                 {
5551                         0u,                                                                                                     // deUint32                     attachment;
5552                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
5553                 };
5554
5555                 const VkSubpassDescription              subpassDescription                      =
5556                 {
5557                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
5558                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
5559                         0u,                                                                     // deUint32                                             inputAttachmentCount;
5560                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
5561                         1u,                                                                     // deUint32                                             colorAttachmentCount;
5562                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
5563                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
5564                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
5565                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
5566                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
5567                 };
5568
5569                 const VkRenderPassCreateInfo    renderPassParams                        =
5570                 {
5571                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
5572                         DE_NULL,                                                                        // const void*                                          pNext;
5573                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
5574                         1u,                                                                                     // deUint32                                                     attachmentCount;
5575                         attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments;
5576                         1u,                                                                                     // deUint32                                                     subpassCount;
5577                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
5578                         0u,                                                                                     // deUint32                                                     dependencyCount;
5579                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
5580                 };
5581
5582                 renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
5583         }
5584
5585         // Create pipeline layout
5586         {
5587                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
5588                 {
5589                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
5590                         DE_NULL,                                                                                        // const void*                                          pNext;
5591                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
5592                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
5593                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
5594                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
5595                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
5596                 };
5597
5598                 pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5599         }
5600
5601         // Create upper half triangle.
5602         {
5603                 const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
5604                 const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
5605                 const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
5606                 // Add triangle.
5607                 vertices.push_back(a);
5608                 vertices.push_back(c);
5609                 vertices.push_back(b);
5610         }
5611
5612         // Create vertex buffer.
5613         {
5614                 const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
5615                 const VkBufferCreateInfo        vertexBufferParams      =
5616                 {
5617                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
5618                         DE_NULL,                                                                        // const void*                  pNext;
5619                         0u,                                                                                     // VkBufferCreateFlags  flags;
5620                         vertexDataSize,                                                         // VkDeviceSize                 size;
5621                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
5622                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
5623                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
5624                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
5625                 };
5626
5627                 vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
5628                 vertexBufferAlloc       = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
5629                 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
5630
5631                 // Load vertices into vertex buffer.
5632                 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
5633                 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
5634         }
5635
5636         {
5637                 Move<VkFramebuffer>             framebuffer;
5638                 Move<VkImageView>               sourceAttachmentView;
5639
5640                 // Create color attachment view.
5641                 {
5642                         const VkImageViewCreateInfo     colorAttachmentViewParams       =
5643                         {
5644                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
5645                                 DE_NULL,                                                                                                // const void*                          pNext;
5646                                 0u,                                                                                                             // VkImageViewCreateFlags       flags;
5647                                 *m_multisampledImage,                                                                   // VkImage                                      image;
5648                                 VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
5649                                 m_params.src.image.format,                                                              // VkFormat                                     format;
5650                                 componentMappingRGBA,                                                                   // VkComponentMapping           components;
5651                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
5652                         };
5653                         sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
5654                 }
5655
5656                 // Create framebuffer
5657                 {
5658                         const VkImageView                               attachments[1]          =
5659                         {
5660                                         *sourceAttachmentView,
5661                         };
5662
5663                         const VkFramebufferCreateInfo   framebufferParams       =
5664                         {
5665                                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
5666                                         DE_NULL,                                                                                        // const void*                                  pNext;
5667                                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
5668                                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
5669                                         1u,                                                                                                     // deUint32                                             attachmentCount;
5670                                         attachments,                                                                            // const VkImageView*                   pAttachments;
5671                                         m_params.src.image.extent.width,                                        // deUint32                                             width;
5672                                         m_params.src.image.extent.height,                                       // deUint32                                             height;
5673                                         1u                                                                                                      // deUint32                                             layers;
5674                         };
5675
5676                         framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
5677                 }
5678
5679                 // Create pipeline
5680                 {
5681                         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
5682                         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
5683
5684                         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
5685                         {
5686                                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
5687                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
5688                                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
5689                                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
5690                                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
5691                                 0.0f,                                                                                                           // float                                                                        minSampleShading;
5692                                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
5693                                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
5694                                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
5695                         };
5696
5697                         graphicsPipeline = makeGraphicsPipeline(vk,                                                                             // const DeviceInterface&                        vk
5698                                                                                                         vkDevice,                                                               // const VkDevice                                device
5699                                                                                                         *pipelineLayout,                                                // const VkPipelineLayout                        pipelineLayout
5700                                                                                                         *vertexShaderModule,                                    // const VkShaderModule                          vertexShaderModule
5701                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
5702                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
5703                                                                                                         DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
5704                                                                                                         *fragmentShaderModule,                                  // const VkShaderModule                          fragmentShaderModule
5705                                                                                                         *renderPass,                                                    // const VkRenderPass                            renderPass
5706                                                                                                         viewports,                                                              // const std::vector<VkViewport>&                viewports
5707                                                                                                         scissors,                                                               // const std::vector<VkRect2D>&                  scissors
5708                                                                                                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
5709                                                                                                         0u,                                                                             // const deUint32                                subpass
5710                                                                                                         0u,                                                                             // const deUint32                                patchControlPoints
5711                                                                                                         DE_NULL,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
5712                                                                                                         DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5713                                                                                                         &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
5714                 }
5715
5716                 // Create command buffer
5717                 {
5718                         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
5719                         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);
5720                         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));
5721
5722                         const VkDeviceSize      vertexBufferOffset      = 0u;
5723
5724                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5725                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5726                         vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
5727
5728                         endRenderPass(vk, *m_cmdBuffer);
5729                         endCommandBuffer(vk, *m_cmdBuffer);
5730                 }
5731
5732                 // Queue submit.
5733                 {
5734                         const VkQueue   queue   = m_context.getUniversalQueue();
5735                         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
5736                 }
5737         }
5738 }
5739
5740 tcu::TestStatus ResolveImageToImage::iterate (void)
5741 {
5742         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
5743         const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
5744
5745         // upload the destination image
5746         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
5747                                                                                                                                                         (int)m_params.dst.image.extent.width,
5748                                                                                                                                                         (int)m_params.dst.image.extent.height,
5749                                                                                                                                                         (int)m_params.dst.image.extent.depth));
5750         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
5751         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
5752
5753         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
5754                                                                                                                                         (int)m_params.src.image.extent.width,
5755                                                                                                                                         (int)m_params.src.image.extent.height,
5756                                                                                                                                         (int)m_params.dst.image.extent.depth));
5757
5758         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);
5759         generateExpectedResult();
5760
5761         VkImage         sourceImage             = m_multisampledImage.get();
5762         deUint32        sourceArraySize = getArraySize(m_params.src.image);
5763
5764         switch (m_options)
5765         {
5766                 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5767                         // Duplicate the multisampled image to a multisampled image array
5768                         sourceArraySize = getArraySize(m_params.dst.image); // fall through
5769                 case COPY_MS_IMAGE_TO_MS_IMAGE:
5770                         copyMSImageToMSImage(sourceArraySize);
5771                         sourceImage     = m_multisampledCopyImage.get();
5772                         break;
5773                 default:
5774                         break;
5775         }
5776
5777         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
5778         const VkDevice                                  vkDevice                        = m_context.getDevice();
5779         const VkQueue                                   queue                           = m_context.getUniversalQueue();
5780
5781         std::vector<VkImageResolve>             imageResolves;
5782         std::vector<VkImageResolve2KHR> imageResolves2KHR;
5783         for (deUint32 i = 0; i < m_params.regions.size(); i++)
5784         {
5785                 if (m_params.extensionUse == EXTENSION_USE_NONE)
5786                 {
5787                         imageResolves.push_back(m_params.regions[i].imageResolve);
5788                 }
5789                 else
5790                 {
5791                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5792                         imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
5793                 }
5794         }
5795
5796         const VkImageMemoryBarrier      imageBarriers[]         =
5797         {
5798                 // source image
5799                 {
5800                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5801                         DE_NULL,                                                                        // const void*                          pNext;
5802                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
5803                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
5804                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
5805                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
5806                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5807                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5808                         sourceImage,                                                            // VkImage                                      image;
5809                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5810                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
5811                                 0u,                                                                     // deUint32                             baseMipLevel;
5812                                 1u,                                                                     // deUint32                             mipLevels;
5813                                 0u,                                                                     // deUint32                             baseArraySlice;
5814                                 sourceArraySize                                         // deUint32                             arraySize;
5815                         }
5816                 },
5817                 // destination image
5818                 {
5819                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5820                         DE_NULL,                                                                        // const void*                          pNext;
5821                         0u,                                                                                     // VkAccessFlags                        srcAccessMask;
5822                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
5823                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
5824                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
5825                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5826                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5827                         m_destination.get(),                                            // VkImage                                      image;
5828                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5829                                 getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
5830                                 0u,                                                                     // deUint32                             baseMipLevel;
5831                                 1u,                                                                     // deUint32                             mipLevels;
5832                                 0u,                                                                     // deUint32                             baseArraySlice;
5833                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
5834                         }
5835                 },
5836         };
5837
5838         const VkImageMemoryBarrier postImageBarrier =
5839         {
5840                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
5841                 DE_NULL,                                                                // const void*                          pNext;
5842                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask;
5843                 VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags                        dstAccessMask;
5844                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        oldLayout;
5845                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
5846                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
5847                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
5848                 m_destination.get(),                                    // VkImage                                      image;
5849                 {                                                                               // VkImageSubresourceRange      subresourceRange;
5850                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags           aspectMask;
5851                         0u,                                                                     // deUint32                                     baseMipLevel;
5852                         1u,                                                                     // deUint32                                     mipLevels;
5853                         0u,                                                                     // deUint32                                     baseArraySlice;
5854                         getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
5855                 }
5856         };
5857
5858         beginCommandBuffer(vk, *m_cmdBuffer);
5859         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);
5860
5861         if (m_params.extensionUse == EXTENSION_USE_NONE)
5862         {
5863                 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());
5864         }
5865         else
5866         {
5867                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5868                 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
5869                 {
5870                         VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,     // VkStructureType                              sType;
5871                         DE_NULL,                                                                        // const void*                                  pNext;
5872                         sourceImage,                                                            // VkImage                                              srcImage;
5873                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                                srcImageLayout;
5874                         m_destination.get(),                                            // VkImage                                              dstImage;
5875                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                                dstImageLayout;
5876                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
5877                         imageResolves2KHR.data()                                        // const  VkImageResolve2KHR*   pRegions;
5878                 };
5879                 vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
5880         }
5881
5882         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);
5883         endCommandBuffer(vk, *m_cmdBuffer);
5884         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5885
5886         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
5887
5888         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
5889         {
5890                 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
5891                 // resolving the image and giving every sample the same value.
5892                 const auto intermediateResult = checkIntermediateCopy();
5893                 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
5894                         return intermediateResult;
5895         }
5896
5897         return checkTestResult(resultTextureLevel->getAccess());
5898 }
5899
5900 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
5901 {
5902         const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel[0]->getAccess();
5903         const float                                                     fuzzyThreshold  = 0.01f;
5904
5905         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
5906         {
5907                 const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
5908                 const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
5909                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
5910                         return tcu::TestStatus::fail("CopiesAndBlitting test");
5911         }
5912
5913         return tcu::TestStatus::pass("CopiesAndBlitting test");
5914 }
5915
5916 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5917 {
5918         DE_UNREF(mipLevel);
5919
5920         VkOffset3D srcOffset    = region.imageResolve.srcOffset;
5921                         srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
5922         VkOffset3D dstOffset    = region.imageResolve.dstOffset;
5923                         dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
5924         VkExtent3D extent               = region.imageResolve.extent;
5925                         extent.depth            = region.imageResolve.srcSubresource.layerCount;
5926
5927         const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
5928         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
5929         const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
5930         const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
5931
5932         tcu::copy(dstSubRegion, srcSubRegion);
5933 }
5934
5935 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
5936 {
5937         const           auto&   vkd                                     = m_context.getDeviceInterface();
5938         const           auto    device                          = m_context.getDevice();
5939         const           auto    queue                           = m_context.getUniversalQueue();
5940         const           auto    queueIndex                      = m_context.getUniversalQueueFamilyIndex();
5941                                 auto&   alloc                           = m_context.getDefaultAllocator();
5942         const           auto    currentLayout           = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5943         const           auto    numDstLayers            = getArraySize(m_params.dst.image);
5944         const           auto    numInputAttachments     = numDstLayers + 1u; // For the source image.
5945         constexpr       auto    numSets                         = 2u; // 1 for the output buffer, 1 for the input attachments.
5946         const           auto    fbWidth                         = m_params.src.image.extent.width;
5947         const           auto    fbHeight                        = m_params.src.image.extent.height;
5948
5949         // Push constants.
5950         const std::array<int, 3> pushConstantData =
5951         {{
5952                 static_cast<int>(fbWidth),
5953                 static_cast<int>(fbHeight),
5954                 static_cast<int>(m_params.samples),
5955         }};
5956         const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
5957
5958         // Shader modules.
5959         const auto vertexModule                 = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
5960         const auto verificationModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
5961
5962         // Descriptor sets.
5963         DescriptorPoolBuilder poolBuilder;
5964         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
5965         poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
5966         const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
5967
5968         DescriptorSetLayoutBuilder layoutBuilderBuffer;
5969         layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
5970         const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
5971
5972         DescriptorSetLayoutBuilder layoutBuilderAttachments;
5973         for (deUint32 i = 0u; i < numInputAttachments; ++i)
5974                 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
5975         const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
5976
5977         const auto descriptorSetBuffer          = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
5978         const auto descriptorSetAttachments     = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
5979
5980         // Array with raw descriptor sets.
5981         const std::array<VkDescriptorSet, numSets> descriptorSets =
5982         {{
5983                 descriptorSetBuffer.get(),
5984                 descriptorSetAttachments.get(),
5985         }};
5986
5987         // Pipeline layout.
5988         const std::array<VkDescriptorSetLayout, numSets> setLayouts =
5989         {{
5990                 outputBufferSetLayout.get(),
5991                 inputAttachmentsSetLayout.get(),
5992         }};
5993
5994         const VkPushConstantRange pushConstantRange =
5995         {
5996                 VK_SHADER_STAGE_FRAGMENT_BIT,   //      VkShaderStageFlags      stageFlags;
5997                 0u,                                                             //      deUint32                        offset;
5998                 pushConstantSize,                               //      deUint32                        size;
5999         };
6000
6001         const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6002         {
6003                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //      VkStructureType                                 sType;
6004                 nullptr,                                                                                //      const void*                                             pNext;
6005                 0u,                                                                                             //      VkPipelineLayoutCreateFlags             flags;
6006                 static_cast<deUint32>(setLayouts.size()),               //      deUint32                                                setLayoutCount;
6007                 setLayouts.data(),                                                              //      const VkDescriptorSetLayout*    pSetLayouts;
6008                 1u,                                                                                             //      deUint32                                                pushConstantRangeCount;
6009                 &pushConstantRange,                                                             //      const VkPushConstantRange*              pPushConstantRanges;
6010         };
6011
6012         const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6013
6014         // Render pass.
6015         const VkAttachmentDescription commonAttachmentDescription =
6016         {
6017                 0u,                                                                     //      VkAttachmentDescriptionFlags    flags;
6018                 m_params.src.image.format,                      //      VkFormat                                                format;
6019                 m_params.samples,                                       //      VkSampleCountFlagBits                   samples;
6020                 VK_ATTACHMENT_LOAD_OP_LOAD,                     //      VkAttachmentLoadOp                              loadOp;
6021                 VK_ATTACHMENT_STORE_OP_STORE,           //      VkAttachmentStoreOp                             storeOp;
6022                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,        //      VkAttachmentLoadOp                              stencilLoadOp;
6023                 VK_ATTACHMENT_STORE_OP_DONT_CARE,       //      VkAttachmentStoreOp                             stencilStoreOp;
6024                 currentLayout,                                          //      VkImageLayout                                   initialLayout;
6025                 currentLayout,                                          //      VkImageLayout                                   finalLayout;
6026         };
6027         const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6028
6029         std::vector<VkAttachmentReference> inputAttachmentReferences;
6030         inputAttachmentReferences.reserve(numInputAttachments);
6031         for (deUint32 i = 0u; i < numInputAttachments; ++i)
6032         {
6033                 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6034                 inputAttachmentReferences.push_back(reference);
6035         }
6036
6037         const VkSubpassDescription subpassDescription =
6038         {
6039                 0u,                                                                                                                     //      VkSubpassDescriptionFlags               flags;
6040                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                                        //      VkPipelineBindPoint                             pipelineBindPoint;
6041                 static_cast<deUint32>(inputAttachmentReferences.size()),        //      deUint32                                                inputAttachmentCount;
6042                 inputAttachmentReferences.data(),                                                       //      const VkAttachmentReference*    pInputAttachments;
6043                 0u,                                                                                                                     //      deUint32                                                colorAttachmentCount;
6044                 nullptr,                                                                                                        //      const VkAttachmentReference*    pColorAttachments;
6045                 nullptr,                                                                                                        //      const VkAttachmentReference*    pResolveAttachments;
6046                 nullptr,                                                                                                        //      const VkAttachmentReference*    pDepthStencilAttachment;
6047                 0u,                                                                                                                     //      deUint32                                                preserveAttachmentCount;
6048                 nullptr,                                                                                                        //      const deUint32*                                 pPreserveAttachments;
6049         };
6050
6051         const VkRenderPassCreateInfo renderPassInfo =
6052         {
6053                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              //      VkStructureType                                 sType;
6054                 nullptr,                                                                                                //      const void*                                             pNext;
6055                 0u,                                                                                                             //      VkRenderPassCreateFlags                 flags;
6056                 static_cast<deUint32>(attachmentDescriptions.size()),   //      deUint32                                                attachmentCount;
6057                 attachmentDescriptions.data(),                                                  //      const VkAttachmentDescription*  pAttachments;
6058                 1u,                                                                                                             //      deUint32                                                subpassCount;
6059                 &subpassDescription,                                                                    //      const VkSubpassDescription*             pSubpasses;
6060                 0u,                                                                                                             //      deUint32                                                dependencyCount;
6061                 nullptr,                                                                                                //      const VkSubpassDependency*              pDependencies;
6062         };
6063
6064         const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6065
6066         // Framebuffer.
6067         std::vector<Move<VkImageView>>  imageViews;
6068         std::vector<VkImageView>                imageViewsRaw;
6069
6070         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)));
6071         for (deUint32 i = 0u; i < numDstLayers; ++i)
6072         {
6073                 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6074                 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6075         }
6076
6077         imageViewsRaw.reserve(imageViews.size());
6078         std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6079
6080         const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6081
6082         // Storage buffer.
6083         const auto                      bufferCount     = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6084         const auto                      bufferSize      = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6085         BufferWithMemory        buffer          (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6086         auto&                           bufferAlloc     = buffer.getAllocation();
6087         void*                           bufferData      = bufferAlloc.getHostPtr();
6088
6089         // Update descriptor sets.
6090         DescriptorSetUpdateBuilder updater;
6091
6092         const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6093         updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6094
6095         std::vector<VkDescriptorImageInfo> imageInfos;
6096         imageInfos.reserve(imageViewsRaw.size());
6097         for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6098                 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6099
6100         for (size_t i = 0; i < imageInfos.size(); ++i)
6101                 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6102
6103         updater.update(vkd, device);
6104
6105         // Vertex buffer.
6106         std::vector<tcu::Vec4> fullScreenQuad;
6107         {
6108                 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6109                 const tcu::Vec4 topLeft         (-1.0f, -1.0f, 0.0f, 1.0f);
6110                 const tcu::Vec4 topRight        ( 1.0f, -1.0f, 0.0f, 1.0f);
6111                 const tcu::Vec4 bottomLeft      (-1.0f,  1.0f, 0.0f, 1.0f);
6112                 const tcu::Vec4 bottomRight     ( 1.0f,  1.0f, 0.0f, 1.0f);
6113
6114                 fullScreenQuad.reserve(6u);
6115                 fullScreenQuad.push_back(topLeft);
6116                 fullScreenQuad.push_back(topRight);
6117                 fullScreenQuad.push_back(bottomRight);
6118                 fullScreenQuad.push_back(topLeft);
6119                 fullScreenQuad.push_back(bottomRight);
6120                 fullScreenQuad.push_back(bottomLeft);
6121         }
6122
6123         const auto                              vertexBufferSize        = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6124         const auto                              vertexBufferInfo        = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6125         const BufferWithMemory  vertexBuffer            (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6126         const auto                              vertexBufferHandler     = vertexBuffer.get();
6127         auto&                                   vertexBufferAlloc       = vertexBuffer.getAllocation();
6128         void*                                   vertexBufferData        = vertexBufferAlloc.getHostPtr();
6129         const VkDeviceSize              vertexBufferOffset      = 0ull;
6130
6131         deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6132         flushAlloc(vkd, device, vertexBufferAlloc);
6133
6134         // Graphics pipeline.
6135         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
6136         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
6137
6138         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
6139         {
6140                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
6141                 nullptr,                                                                                                        // const void*                                                          pNext;
6142                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
6143                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
6144                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
6145                 0.0f,                                                                                                           // float                                                                        minSampleShading;
6146                 nullptr,                                                                                                        // const VkSampleMask*                                          pSampleMask;
6147                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
6148                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
6149         };
6150
6151         const auto graphicsPipeline = makeGraphicsPipeline(
6152                 vkd,                                                                    // const DeviceInterface&                        vk
6153                 device,                                                                 // const VkDevice                                device
6154                 pipelineLayout.get(),                                   // const VkPipelineLayout                        pipelineLayout
6155                 vertexModule.get(),                                             // const VkShaderModule                          vertexShaderModule
6156                 DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
6157                 DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
6158                 DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
6159                 verificationModule.get(),                               // const VkShaderModule                          fragmentShaderModule
6160                 renderPass.get(),                                               // const VkRenderPass                            renderPass
6161                 viewports,                                                              // const std::vector<VkViewport>&                viewports
6162                 scissors,                                                               // const std::vector<VkRect2D>&                  scissors
6163                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
6164                 0u,                                                                             // const deUint32                                subpass
6165                 0u,                                                                             // const deUint32                                patchControlPoints
6166                 nullptr,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6167                 nullptr,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6168                 &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6169
6170         // Command buffer.
6171         const auto cmdPool              = makeCommandPool(vkd, device, queueIndex);
6172         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6173         const auto cmdBuffer    = cmdBufferPtr.get();
6174
6175         // Make sure multisample copy data is available to the fragment shader.
6176         const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6177
6178         // Make sure verification buffer data is available on the host.
6179         const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6180
6181         // Record and submit command buffer.
6182         beginCommandBuffer(vkd, cmdBuffer);
6183         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6184         beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6185         vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6186         vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6187         vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6188         vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6189         vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6190         endRenderPass(vkd, cmdBuffer);
6191         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6192         endCommandBuffer(vkd, cmdBuffer);
6193         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6194
6195         // Verify intermediate results.
6196         invalidateAlloc(vkd, device, bufferAlloc);
6197         std::vector<deInt32> outputFlags (bufferCount, 0);
6198         deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6199
6200         auto& log = m_context.getTestContext().getLog();
6201         log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6202
6203         const auto sampleCount = static_cast<deUint32>(m_params.samples);
6204
6205         for (deUint32 x = 0u; x < fbWidth; ++x)
6206         for (deUint32 y = 0u; y < fbHeight; ++y)
6207         for (deUint32 s = 0u; s < sampleCount; ++s)
6208         {
6209                 const auto index = (y * fbWidth + x) * sampleCount + s;
6210                 if (!outputFlags[index])
6211                 {
6212                         std::ostringstream msg;
6213                         msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6214                         return tcu::TestStatus::fail(msg.str());
6215                 }
6216         }
6217
6218         log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6219         return tcu::TestStatus::pass("Pass");
6220 }
6221
6222 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6223 {
6224         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
6225         const VkDevice                                  vkDevice                        = m_context.getDevice();
6226         const VkQueue                                   queue                           = m_context.getUniversalQueue();
6227         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
6228         std::vector<VkImageCopy>                imageCopies;
6229         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
6230
6231         for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6232         {
6233                 const VkImageSubresourceLayers  sourceSubresourceLayers =
6234                 {
6235                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
6236                         0u,                                                             // deUint32                             mipLevel;
6237                         0u,                                                             // deUint32                             baseArrayLayer;
6238                         1u                                                              // deUint32                             layerCount;
6239                 };
6240
6241                 const VkImageSubresourceLayers  destinationSubresourceLayers    =
6242                 {
6243                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
6244                         0u,                                                             // deUint32                             mipLevel;
6245                         layerNdx,                                               // deUint32                             baseArrayLayer;
6246                         1u                                                              // deUint32                             layerCount;
6247                 };
6248
6249                 const VkImageCopy                               imageCopy       =
6250                 {
6251                         sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
6252                         {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
6253                         destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
6254                         {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
6255                          getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
6256                 };
6257
6258                 if (m_params.extensionUse == EXTENSION_USE_NONE)
6259                 {
6260                         imageCopies.push_back(imageCopy);
6261                 }
6262                 else
6263                 {
6264                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6265                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6266                 }
6267         }
6268
6269         const VkImageMemoryBarrier              imageBarriers[]         =
6270         {
6271                 // source image
6272                 {
6273                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6274                         DE_NULL,                                                                        // const void*                          pNext;
6275                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
6276                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
6277                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
6278                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
6279                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6280                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6281                         m_multisampledImage.get(),                                      // VkImage                                      image;
6282                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
6283                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6284                                 0u,                                                                     // deUint32                             baseMipLevel;
6285                                 1u,                                                                     // deUint32                             mipLevels;
6286                                 0u,                                                                     // deUint32                             baseArraySlice;
6287                                 getArraySize(m_params.src.image)        // deUint32                             arraySize;
6288                         }
6289                 },
6290                 // destination image
6291                 {
6292                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6293                         DE_NULL,                                                                        // const void*                          pNext;
6294                         0,                                                                                      // VkAccessFlags                        srcAccessMask;
6295                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
6296                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
6297                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
6298                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6299                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6300                         m_multisampledCopyImage.get(),                          // VkImage                                      image;
6301                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
6302                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6303                                 0u,                                                                     // deUint32                             baseMipLevel;
6304                                 1u,                                                                     // deUint32                             mipLevels;
6305                                 0u,                                                                     // deUint32                             baseArraySlice;
6306                                 copyArraySize                                           // deUint32                             arraySize;
6307                         }
6308                 },
6309         };
6310
6311         const VkImageMemoryBarrier      postImageBarriers               =
6312         // destination image
6313         {
6314                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6315                 DE_NULL,                                                                        // const void*                          pNext;
6316                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
6317                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
6318                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
6319                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
6320                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6321                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6322                 m_multisampledCopyImage.get(),                          // VkImage                                      image;
6323                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
6324                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6325                         0u,                                                                     // deUint32                             baseMipLevel;
6326                         1u,                                                                     // deUint32                             mipLevels;
6327                         0u,                                                                     // deUint32                             baseArraySlice;
6328                         copyArraySize                                           // deUint32                             arraySize;
6329                 }
6330         };
6331
6332         beginCommandBuffer(vk, *m_cmdBuffer);
6333         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);
6334
6335         if (m_params.extensionUse == EXTENSION_USE_NONE)
6336         {
6337                 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());
6338         }
6339         else
6340         {
6341                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6342                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
6343                 {
6344                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
6345                         DE_NULL,                                                                        // const void*                          pNext;
6346                         m_multisampledImage.get(),                                      // VkImage                                      srcImage;
6347                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        srcImageLayout;
6348                         m_multisampledCopyImage.get(),                          // VkImage                                      dstImage;
6349                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        dstImageLayout;
6350                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
6351                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
6352                 };
6353
6354                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
6355         }
6356
6357         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);
6358         endCommandBuffer(vk, *m_cmdBuffer);
6359
6360         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
6361 }
6362
6363 class ResolveImageToImageTestCase : public vkt::TestCase
6364 {
6365 public:
6366                                                         ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
6367                                                                                                                  const std::string&                                     name,
6368                                                                                                                  const std::string&                                     description,
6369                                                                                                                  const TestParams                                       params,
6370                                                                                                                  const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
6371                                                                 : vkt::TestCase (testCtx, name, description)
6372                                                                 , m_params              (params)
6373                                                                 , m_options             (options)
6374         {}
6375
6376                                                         virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
6377
6378         virtual TestInstance*   createInstance                          (Context&                               context) const
6379         {
6380                 return new ResolveImageToImage(context, m_params, m_options);
6381         }
6382
6383         virtual void                    checkSupport                            (Context&                               context) const
6384         {
6385                 const VkSampleCountFlagBits     rasterizationSamples = m_params.samples;
6386
6387                 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
6388                         throw tcu::NotSupportedError("Unsupported number of rasterization samples");
6389
6390                 VkImageFormatProperties properties;
6391                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6392                                                                                                                                                                         m_params.src.image.format,
6393                                                                                                                                                                         m_params.src.image.imageType,
6394                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
6395                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
6396                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
6397                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6398                                                                                                                                                                         m_params.dst.image.format,
6399                                                                                                                                                                         m_params.dst.image.imageType,
6400                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
6401                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
6402                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
6403                 {
6404                         TCU_THROW(NotSupportedError, "Format not supported");
6405                 }
6406
6407                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)     &&
6408                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
6409                 {
6410                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
6411                 }
6412         }
6413
6414 private:
6415         TestParams                                                      m_params;
6416         const ResolveImageToImageOptions        m_options;
6417 };
6418
6419 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
6420 {
6421         programCollection.glslSources.add("vert") << glu::VertexSource(
6422                 "#version 310 es\n"
6423                 "layout (location = 0) in highp vec4 a_position;\n"
6424                 "void main()\n"
6425                 "{\n"
6426                 "       gl_Position = a_position;\n"
6427                 "}\n");
6428
6429
6430         programCollection.glslSources.add("frag") << glu::FragmentSource(
6431                 "#version 310 es\n"
6432                 "layout (location = 0) out highp vec4 o_color;\n"
6433                 "void main()\n"
6434                 "{\n"
6435                 "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6436                 "}\n");
6437
6438         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
6439         {
6440                 // The shader verifies all layers in the copied image are the same as the source image.
6441                 // This needs an image view per layer in the copied image.
6442                 // Set 0 contains the output buffer.
6443                 // Set 1 contains the input attachments.
6444
6445                 std::ostringstream verificationShader;
6446
6447                 verificationShader
6448                         << "#version 450\n"
6449                         << "\n"
6450                         << "layout (push_constant, std430) uniform PushConstants {\n"
6451                         << "    int width;\n"
6452                         << "    int height;\n"
6453                         << "    int samples;\n"
6454                         << "};\n"
6455                         << "layout (set=0, binding=0) buffer VerificationResults {\n"
6456                         << "    int verificationFlags[];\n"
6457                         << "};\n"
6458                         << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
6459                         ;
6460
6461                 const auto dstLayers = getArraySize(m_params.dst.image);
6462                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6463                 {
6464                         const auto i = layerNdx + 1u;
6465                         verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
6466                 }
6467
6468                 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
6469                 // created with a single sample.
6470                 verificationShader
6471                         << "\n"
6472                         << "void main() {\n"
6473                         << "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
6474                         << "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
6475                         ;
6476
6477                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6478                 {
6479                         const auto i = layerNdx + 1u;
6480                         verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
6481                 }
6482
6483                 std::ostringstream testCondition;
6484                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6485                 {
6486                         const auto i = layerNdx + 1u;
6487                         testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
6488                 }
6489
6490                 verificationShader
6491                         << "\n"
6492                         << "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
6493                         << "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
6494                         << "\n"
6495                         << "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
6496                         << "    }\n"
6497                         << "}\n"
6498                         ;
6499
6500                 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
6501         }
6502 }
6503
6504 struct BufferOffsetParams
6505 {
6506         static constexpr deUint32 kMaxOffset = 8u;
6507
6508         deUint32 srcOffset;
6509         deUint32 dstOffset;
6510 };
6511
6512 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
6513 {
6514         constexpr deUint8 zero{0};
6515         for (deUint32 i = 0; i < count; ++i)
6516         {
6517                 const auto& val = bufferData[from + i];
6518                 if (val != zero)
6519                 {
6520                         std::ostringstream msg;
6521                         msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
6522                         TCU_FAIL(msg.str());
6523                 }
6524         }
6525 }
6526
6527 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
6528 {
6529         // 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.
6530         constexpr auto kMaxOffset       = BufferOffsetParams::kMaxOffset;
6531         constexpr auto kBlockSize       = kMaxOffset * 2u;
6532         constexpr auto kBufferSize      = kMaxOffset * kBlockSize;
6533
6534         DE_ASSERT(params.srcOffset < kMaxOffset);
6535         DE_ASSERT(params.dstOffset < kMaxOffset);
6536
6537         const auto&     vkd             = ctx.getDeviceInterface();
6538         const auto      device  = ctx.getDevice();
6539         auto&           alloc   = ctx.getDefaultAllocator();
6540         const auto      qIndex  = ctx.getUniversalQueueFamilyIndex();
6541         const auto      queue   = ctx.getUniversalQueue();
6542
6543         const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
6544         const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6545
6546         BufferWithMemory        srcBuffer       (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
6547         BufferWithMemory        dstBuffer       (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
6548         auto&                           srcAlloc        = srcBuffer.getAllocation();
6549         auto&                           dstAlloc        = dstBuffer.getAllocation();
6550
6551         // Zero-out destination buffer.
6552         deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
6553         flushAlloc(vkd, device, dstAlloc);
6554
6555         // Fill source buffer with nonzero bytes.
6556         std::vector<deUint8> srcData;
6557         srcData.reserve(kBufferSize);
6558         for (deUint32 i = 0; i < kBufferSize; ++i)
6559                 srcData.push_back(static_cast<deUint8>(100u + i));
6560         deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
6561         flushAlloc(vkd, device, srcAlloc);
6562
6563         // Copy regions.
6564         std::vector<VkBufferCopy> copies;
6565         copies.reserve(kMaxOffset);
6566         for (deUint32 i = 0; i < kMaxOffset; ++i)
6567         {
6568                 const auto blockStart   = kBlockSize * i;
6569                 const auto copySize             = i + 1u;
6570                 const auto bufferCopy   = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
6571                 copies.push_back(bufferCopy);
6572         }
6573
6574         const auto cmdPool              = makeCommandPool(vkd, device, qIndex);
6575         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6576         const auto cmdBuffer    = cmdBufferPtr.get();
6577
6578         beginCommandBuffer(vkd, cmdBuffer);
6579         vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
6580         const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6581         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
6582         endCommandBuffer(vkd, cmdBuffer);
6583         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6584         invalidateAlloc(vkd, device, dstAlloc);
6585
6586         // Verify destination buffer data.
6587         std::vector<deUint8> dstData(kBufferSize);
6588         deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
6589
6590         for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
6591         {
6592                 const auto blockStart   = kBlockSize * blockIdx;
6593                 const auto copySize             = blockIdx + 1u;
6594
6595                 // Verify no data has been written before dstOffset.
6596                 checkZerosAt(dstData, blockStart, params.dstOffset);
6597
6598                 // Verify copied block.
6599                 for (deUint32 i = 0; i < copySize; ++i)
6600                 {
6601                         const auto& dstVal = dstData[blockStart + params.dstOffset + i];
6602                         const auto& srcVal = srcData[blockStart + params.srcOffset + i];
6603                         if (dstVal != srcVal)
6604                         {
6605                                 std::ostringstream msg;
6606                                 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
6607                                 TCU_FAIL(msg.str());
6608                         }
6609                 }
6610
6611                 // Verify no data has been written after copy block.
6612                 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
6613         }
6614
6615         return tcu::TestStatus::pass("Pass");
6616 }
6617
6618 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
6619 {
6620         return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
6621 }
6622
6623 std::string getFormatCaseName (VkFormat format)
6624 {
6625         return de::toLower(de::toString(getFormatStr(format)).substr(10));
6626 }
6627
6628 std::string getImageLayoutCaseName (VkImageLayout layout)
6629 {
6630         switch (layout)
6631         {
6632                 case VK_IMAGE_LAYOUT_GENERAL:
6633                         return "general";
6634                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
6635                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
6636                         return "optimal";
6637                 default:
6638                         DE_ASSERT(false);
6639                         return "";
6640         }
6641 }
6642
6643 const deInt32                                   defaultSize                             = 64;
6644 const deInt32                                   defaultHalfSize                 = defaultSize / 2;
6645 const deInt32                                   defaultFourthSize               = defaultSize / 4;
6646 const deInt32                                   defaultSixteenthSize    = defaultSize / 16;
6647 const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
6648 const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
6649 const VkExtent3D                                default1dExtent                 = {defaultSize, 1, 1};
6650 const VkExtent3D                                default3dExtent                 = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
6651
6652 const VkImageSubresourceLayers  defaultSourceLayer              =
6653 {
6654         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6655         0u,                                                     // deUint32                             mipLevel;
6656         0u,                                                     // deUint32                             baseArrayLayer;
6657         1u,                                                     // deUint32                             layerCount;
6658 };
6659
6660 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6661 {
6662         tcu::TestContext& testCtx       = group->getTestContext();
6663
6664         {
6665                 TestParams      params;
6666                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6667                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6668                 params.src.image.extent                         = defaultExtent;
6669                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6670                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6671                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6672                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6673                 params.dst.image.extent                         = defaultExtent;
6674                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6675                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6676                 params.allocationKind                           = allocationKind;
6677                 params.extensionUse                                     = extensionUse;
6678
6679                 {
6680                         const VkImageCopy                               testCopy        =
6681                         {
6682                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6683                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
6684                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6685                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6686                                 defaultExtent,          // VkExtent3D                           extent;
6687                         };
6688
6689                         CopyRegion      imageCopy;
6690                         imageCopy.imageCopy     = testCopy;
6691                         params.regions.push_back(imageCopy);
6692                 }
6693
6694                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
6695         }
6696
6697         {
6698                 TestParams      params;
6699                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6700                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6701                 params.src.image.extent                         = defaultExtent;
6702                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6703                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6704                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6705                 params.dst.image.format                         = VK_FORMAT_R32_UINT;
6706                 params.dst.image.extent                         = defaultExtent;
6707                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6708                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6709                 params.allocationKind                           = allocationKind;
6710                 params.extensionUse                                     = extensionUse;
6711
6712                 {
6713                         const VkImageCopy                               testCopy        =
6714                         {
6715                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6716                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
6717                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6718                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6719                                 defaultExtent,          // VkExtent3D                           extent;
6720                         };
6721
6722                         CopyRegion      imageCopy;
6723                         imageCopy.imageCopy = testCopy;
6724                         params.regions.push_back(imageCopy);
6725                 }
6726
6727                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
6728         }
6729
6730         {
6731                 TestParams      params;
6732                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6733                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6734                 params.src.image.extent                         = defaultExtent;
6735                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6736                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6737                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6738                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6739                 params.dst.image.extent                         = defaultExtent;
6740                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6741                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6742                 params.allocationKind                           = allocationKind;
6743                 params.extensionUse                                     = extensionUse;
6744
6745                 {
6746                         const VkImageCopy                               testCopy        =
6747                         {
6748                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     srcSubresource;
6749                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6750                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     dstSubresource;
6751                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6752                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6753                         };
6754
6755                         CopyRegion      imageCopy;
6756                         imageCopy.imageCopy = testCopy;
6757                         params.regions.push_back(imageCopy);
6758                 }
6759
6760                 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
6761         }
6762
6763         static const struct
6764         {
6765                 std::string             name;
6766                 vk::VkFormat    format1;
6767                 vk::VkFormat    format2;
6768         } formats [] =
6769         {
6770                 { "diff_format",        vk::VK_FORMAT_R32_UINT,                 vk::VK_FORMAT_R8G8B8A8_UNORM    },
6771                 { "same_format",        vk::VK_FORMAT_R8G8B8A8_UNORM,   vk::VK_FORMAT_R8G8B8A8_UNORM    }
6772         };
6773         static const struct
6774         {
6775                 std::string             name;
6776                 vk::VkBool32    clear;
6777         } clears [] =
6778         {
6779                 { "clear",              VK_TRUE         },
6780                 { "noclear",    VK_FALSE        }
6781         };
6782         static const struct
6783         {
6784                 std::string             name;
6785                 VkExtent3D              extent;
6786         } extents [] =
6787         {
6788                 { "npot",       {65u, 63u, 1u}  },
6789                 { "pot",        {64u, 64u, 1u}  }
6790         };
6791
6792         for (const auto& format : formats)
6793         {
6794                 for (const auto& clear : clears)
6795                 {
6796                         for (const auto& extent : extents)
6797                         {
6798                                 TestParams      params;
6799                                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6800                                 params.src.image.format                         = format.format1;
6801                                 params.src.image.extent                         = extent.extent;
6802                                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6803                                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6804                                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6805                                 params.dst.image.format                         = format.format2;
6806                                 params.dst.image.extent                         = extent.extent;
6807                                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6808                                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6809                                 params.allocationKind                           = allocationKind;
6810                                 params.extensionUse                                     = extensionUse;
6811                                 params.clearDestination                         = clear.clear;
6812
6813                                 {
6814                                         VkImageCopy     testCopy        =
6815                                         {
6816                                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6817                                                 {34, 34, 0},            // VkOffset3D                           srcOffset;
6818                                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6819                                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6820                                                 {31, 29, 1}                     // VkExtent3D                           extent;
6821                                         };
6822
6823                                         if (extent.name == "pot")
6824                                         {
6825                                                 testCopy.srcOffset      = { 16, 16, 0 };
6826                                                 testCopy.extent         = { 32, 32, 1 };
6827                                         }
6828
6829                                         CopyRegion      imageCopy;
6830                                         imageCopy.imageCopy = testCopy;
6831                                         params.regions.push_back(imageCopy);
6832                                 }
6833
6834                                 // Example test case name: "partial_image_npot_diff_format_clear"
6835                                 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
6836
6837                                 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
6838                         }
6839                 }
6840         }
6841
6842         {
6843                 TestParams      params;
6844                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6845                 params.src.image.format                         = VK_FORMAT_D32_SFLOAT;
6846                 params.src.image.extent                         = defaultExtent;
6847                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6848                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6849                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6850                 params.dst.image.format                         = VK_FORMAT_D32_SFLOAT;
6851                 params.dst.image.extent                         = defaultExtent;
6852                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6853                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6854                 params.allocationKind                           = allocationKind;
6855                 params.extensionUse                                     = extensionUse;
6856
6857                 {
6858                         const VkImageSubresourceLayers  sourceLayer =
6859                         {
6860                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
6861                                 0u,                                                     // deUint32                             mipLevel;
6862                                 0u,                                                     // deUint32                             baseArrayLayer;
6863                                 1u                                                      // deUint32                             layerCount;
6864                         };
6865                         const VkImageCopy                               testCopy        =
6866                         {
6867                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
6868                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6869                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
6870                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6871                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6872                         };
6873
6874                         CopyRegion      imageCopy;
6875                         imageCopy.imageCopy = testCopy;
6876                         params.regions.push_back(imageCopy);
6877                 }
6878
6879                 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
6880         }
6881
6882         {
6883                 TestParams      params;
6884                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6885                 params.src.image.format                         = VK_FORMAT_S8_UINT;
6886                 params.src.image.extent                         = defaultExtent;
6887                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6888                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6889                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6890                 params.dst.image.format                         = VK_FORMAT_S8_UINT;
6891                 params.dst.image.extent                         = defaultExtent;
6892                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6893                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6894                 params.allocationKind                           = allocationKind;
6895                 params.extensionUse                                     = extensionUse;
6896
6897                 {
6898                         const VkImageSubresourceLayers  sourceLayer =
6899                         {
6900                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
6901                                 0u,                                                             // deUint32                             mipLevel;
6902                                 0u,                                                             // deUint32                             baseArrayLayer;
6903                                 1u                                                              // deUint32                             layerCount;
6904                         };
6905                         const VkImageCopy                               testCopy        =
6906                         {
6907                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
6908                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6909                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
6910                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6911                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6912                         };
6913
6914                         CopyRegion      imageCopy;
6915                         imageCopy.imageCopy = testCopy;
6916                         params.regions.push_back(imageCopy);
6917                 }
6918
6919                 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
6920         }
6921 }
6922
6923 struct CopyColorTestParams
6924 {
6925         TestParams              params;
6926         const VkFormat* compatibleFormats;
6927 };
6928
6929 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
6930 {
6931         const VkImageLayout copySrcLayouts[]            =
6932         {
6933                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6934                 VK_IMAGE_LAYOUT_GENERAL
6935         };
6936         const VkImageLayout copyDstLayouts[]            =
6937         {
6938                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6939                 VK_IMAGE_LAYOUT_GENERAL
6940         };
6941
6942         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
6943         {
6944                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
6945
6946                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
6947                 {
6948                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
6949
6950                         const std::string testName      = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
6951                                                                                   getImageLayoutCaseName(params.dst.image.operationLayout);
6952                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
6953                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
6954                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
6955                 }
6956         }
6957 }
6958
6959 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
6960 {
6961         bool result = true;
6962
6963         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
6964         {
6965                 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
6966
6967                 result =
6968                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
6969                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
6970         }
6971
6972         return result;
6973 }
6974
6975 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
6976 {
6977         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
6978         const VkFormat  srcFormatOnly[2]        = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
6979         const VkFormat* formatList                      = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
6980
6981         for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
6982         {
6983                 testParams.params.dst.image.format = formatList[dstFormatIndex];
6984
6985                 const VkFormat          srcFormat       = testParams.params.src.image.format;
6986                 const VkFormat          dstFormat       = testParams.params.dst.image.format;
6987
6988                 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
6989                         continue;
6990
6991                 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
6992                         continue;
6993
6994                 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
6995                         if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
6996                                 continue;
6997
6998                 const std::string       description     = "Copy to destination format " + getFormatCaseName(dstFormat);
6999                 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
7000         }
7001 }
7002
7003 const VkFormat  compatibleFormats8Bit[]         =
7004 {
7005         VK_FORMAT_R4G4_UNORM_PACK8,
7006         VK_FORMAT_R8_UNORM,
7007         VK_FORMAT_R8_SNORM,
7008         VK_FORMAT_R8_USCALED,
7009         VK_FORMAT_R8_SSCALED,
7010         VK_FORMAT_R8_UINT,
7011         VK_FORMAT_R8_SINT,
7012         VK_FORMAT_R8_SRGB,
7013
7014         VK_FORMAT_UNDEFINED
7015 };
7016 const VkFormat  compatibleFormats16Bit[]        =
7017 {
7018         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7019         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
7020         VK_FORMAT_R5G6B5_UNORM_PACK16,
7021         VK_FORMAT_B5G6R5_UNORM_PACK16,
7022         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
7023         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
7024         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
7025         VK_FORMAT_R8G8_UNORM,
7026         VK_FORMAT_R8G8_SNORM,
7027         VK_FORMAT_R8G8_USCALED,
7028         VK_FORMAT_R8G8_SSCALED,
7029         VK_FORMAT_R8G8_UINT,
7030         VK_FORMAT_R8G8_SINT,
7031         VK_FORMAT_R8G8_SRGB,
7032         VK_FORMAT_R16_UNORM,
7033         VK_FORMAT_R16_SNORM,
7034         VK_FORMAT_R16_USCALED,
7035         VK_FORMAT_R16_SSCALED,
7036         VK_FORMAT_R16_UINT,
7037         VK_FORMAT_R16_SINT,
7038         VK_FORMAT_R16_SFLOAT,
7039         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
7040         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
7041
7042         VK_FORMAT_UNDEFINED
7043 };
7044 const VkFormat  compatibleFormats24Bit[]        =
7045 {
7046         VK_FORMAT_R8G8B8_UNORM,
7047         VK_FORMAT_R8G8B8_SNORM,
7048         VK_FORMAT_R8G8B8_USCALED,
7049         VK_FORMAT_R8G8B8_SSCALED,
7050         VK_FORMAT_R8G8B8_UINT,
7051         VK_FORMAT_R8G8B8_SINT,
7052         VK_FORMAT_R8G8B8_SRGB,
7053         VK_FORMAT_B8G8R8_UNORM,
7054         VK_FORMAT_B8G8R8_SNORM,
7055         VK_FORMAT_B8G8R8_USCALED,
7056         VK_FORMAT_B8G8R8_SSCALED,
7057         VK_FORMAT_B8G8R8_UINT,
7058         VK_FORMAT_B8G8R8_SINT,
7059         VK_FORMAT_B8G8R8_SRGB,
7060
7061         VK_FORMAT_UNDEFINED
7062 };
7063 const VkFormat  compatibleFormats32Bit[]        =
7064 {
7065         VK_FORMAT_R8G8B8A8_UNORM,
7066         VK_FORMAT_R8G8B8A8_SNORM,
7067         VK_FORMAT_R8G8B8A8_USCALED,
7068         VK_FORMAT_R8G8B8A8_SSCALED,
7069         VK_FORMAT_R8G8B8A8_UINT,
7070         VK_FORMAT_R8G8B8A8_SINT,
7071         VK_FORMAT_R8G8B8A8_SRGB,
7072         VK_FORMAT_B8G8R8A8_UNORM,
7073         VK_FORMAT_B8G8R8A8_SNORM,
7074         VK_FORMAT_B8G8R8A8_USCALED,
7075         VK_FORMAT_B8G8R8A8_SSCALED,
7076         VK_FORMAT_B8G8R8A8_UINT,
7077         VK_FORMAT_B8G8R8A8_SINT,
7078         VK_FORMAT_B8G8R8A8_SRGB,
7079         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
7080         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
7081         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
7082         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
7083         VK_FORMAT_A8B8G8R8_UINT_PACK32,
7084         VK_FORMAT_A8B8G8R8_SINT_PACK32,
7085         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
7086         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
7087         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
7088         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
7089         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
7090         VK_FORMAT_A2R10G10B10_UINT_PACK32,
7091         VK_FORMAT_A2R10G10B10_SINT_PACK32,
7092         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
7093         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
7094         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
7095         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
7096         VK_FORMAT_A2B10G10R10_UINT_PACK32,
7097         VK_FORMAT_A2B10G10R10_SINT_PACK32,
7098         VK_FORMAT_R16G16_UNORM,
7099         VK_FORMAT_R16G16_SNORM,
7100         VK_FORMAT_R16G16_USCALED,
7101         VK_FORMAT_R16G16_SSCALED,
7102         VK_FORMAT_R16G16_UINT,
7103         VK_FORMAT_R16G16_SINT,
7104         VK_FORMAT_R16G16_SFLOAT,
7105         VK_FORMAT_R32_UINT,
7106         VK_FORMAT_R32_SINT,
7107         VK_FORMAT_R32_SFLOAT,
7108
7109         VK_FORMAT_UNDEFINED
7110 };
7111 const VkFormat  compatibleFormats48Bit[]        =
7112 {
7113         VK_FORMAT_R16G16B16_UNORM,
7114         VK_FORMAT_R16G16B16_SNORM,
7115         VK_FORMAT_R16G16B16_USCALED,
7116         VK_FORMAT_R16G16B16_SSCALED,
7117         VK_FORMAT_R16G16B16_UINT,
7118         VK_FORMAT_R16G16B16_SINT,
7119         VK_FORMAT_R16G16B16_SFLOAT,
7120
7121         VK_FORMAT_UNDEFINED
7122 };
7123 const VkFormat  compatibleFormats64Bit[]        =
7124 {
7125         VK_FORMAT_R16G16B16A16_UNORM,
7126         VK_FORMAT_R16G16B16A16_SNORM,
7127         VK_FORMAT_R16G16B16A16_USCALED,
7128         VK_FORMAT_R16G16B16A16_SSCALED,
7129         VK_FORMAT_R16G16B16A16_UINT,
7130         VK_FORMAT_R16G16B16A16_SINT,
7131         VK_FORMAT_R16G16B16A16_SFLOAT,
7132         VK_FORMAT_R32G32_UINT,
7133         VK_FORMAT_R32G32_SINT,
7134         VK_FORMAT_R32G32_SFLOAT,
7135         VK_FORMAT_R64_UINT,
7136         VK_FORMAT_R64_SINT,
7137         VK_FORMAT_R64_SFLOAT,
7138
7139         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
7140         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
7141         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
7142         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
7143         VK_FORMAT_BC4_UNORM_BLOCK,
7144         VK_FORMAT_BC4_SNORM_BLOCK,
7145
7146         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
7147         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
7148         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
7149         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
7150
7151         VK_FORMAT_EAC_R11_UNORM_BLOCK,
7152         VK_FORMAT_EAC_R11_SNORM_BLOCK,
7153
7154         VK_FORMAT_UNDEFINED
7155 };
7156 const VkFormat  compatibleFormats96Bit[]        =
7157 {
7158         VK_FORMAT_R32G32B32_UINT,
7159         VK_FORMAT_R32G32B32_SINT,
7160         VK_FORMAT_R32G32B32_SFLOAT,
7161
7162         VK_FORMAT_UNDEFINED
7163 };
7164 const VkFormat  compatibleFormats128Bit[]       =
7165 {
7166         VK_FORMAT_R32G32B32A32_UINT,
7167         VK_FORMAT_R32G32B32A32_SINT,
7168         VK_FORMAT_R32G32B32A32_SFLOAT,
7169         VK_FORMAT_R64G64_UINT,
7170         VK_FORMAT_R64G64_SINT,
7171         VK_FORMAT_R64G64_SFLOAT,
7172
7173         VK_FORMAT_BC2_UNORM_BLOCK,
7174         VK_FORMAT_BC2_SRGB_BLOCK,
7175         VK_FORMAT_BC3_UNORM_BLOCK,
7176         VK_FORMAT_BC3_SRGB_BLOCK,
7177         VK_FORMAT_BC5_UNORM_BLOCK,
7178         VK_FORMAT_BC5_SNORM_BLOCK,
7179         VK_FORMAT_BC6H_UFLOAT_BLOCK,
7180         VK_FORMAT_BC6H_SFLOAT_BLOCK,
7181         VK_FORMAT_BC7_UNORM_BLOCK,
7182         VK_FORMAT_BC7_SRGB_BLOCK,
7183
7184         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
7185         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
7186
7187         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
7188         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
7189
7190         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
7191         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
7192         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
7193         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
7194         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
7195         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
7196         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
7197         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
7198         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
7199         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
7200         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
7201         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
7202         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
7203         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
7204         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
7205         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
7206         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
7207         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
7208         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
7209         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
7210         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
7211         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
7212         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
7213         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
7214         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
7215         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
7216         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
7217         VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
7218
7219         VK_FORMAT_UNDEFINED
7220 };
7221 const VkFormat  compatibleFormats192Bit[]       =
7222 {
7223         VK_FORMAT_R64G64B64_UINT,
7224         VK_FORMAT_R64G64B64_SINT,
7225         VK_FORMAT_R64G64B64_SFLOAT,
7226
7227         VK_FORMAT_UNDEFINED
7228 };
7229 const VkFormat  compatibleFormats256Bit[]       =
7230 {
7231         VK_FORMAT_R64G64B64A64_UINT,
7232         VK_FORMAT_R64G64B64A64_SINT,
7233         VK_FORMAT_R64G64B64A64_SFLOAT,
7234
7235         VK_FORMAT_UNDEFINED
7236 };
7237
7238 const VkFormat* colorImageFormatsToTest[]       =
7239 {
7240         compatibleFormats8Bit,
7241         compatibleFormats16Bit,
7242         compatibleFormats24Bit,
7243         compatibleFormats32Bit,
7244         compatibleFormats48Bit,
7245         compatibleFormats64Bit,
7246         compatibleFormats96Bit,
7247         compatibleFormats128Bit,
7248         compatibleFormats192Bit,
7249         compatibleFormats256Bit
7250 };
7251
7252 const VkFormat  dedicatedAllocationImageToImageFormatsToTest[]  =
7253 {
7254         // From compatibleFormats8Bit
7255         VK_FORMAT_R4G4_UNORM_PACK8,
7256         VK_FORMAT_R8_SRGB,
7257
7258         // From compatibleFormats16Bit
7259         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7260         VK_FORMAT_R16_SFLOAT,
7261
7262         // From compatibleFormats24Bit
7263         VK_FORMAT_R8G8B8_UNORM,
7264         VK_FORMAT_B8G8R8_SRGB,
7265
7266         // From compatibleFormats32Bit
7267         VK_FORMAT_R8G8B8A8_UNORM,
7268         VK_FORMAT_R32_SFLOAT,
7269
7270         // From compatibleFormats48Bit
7271         VK_FORMAT_R16G16B16_UNORM,
7272         VK_FORMAT_R16G16B16_SFLOAT,
7273
7274         // From compatibleFormats64Bit
7275         VK_FORMAT_R16G16B16A16_UNORM,
7276         VK_FORMAT_R64_SFLOAT,
7277
7278         // From compatibleFormats96Bit
7279         VK_FORMAT_R32G32B32_UINT,
7280         VK_FORMAT_R32G32B32_SFLOAT,
7281
7282         // From compatibleFormats128Bit
7283         VK_FORMAT_R32G32B32A32_UINT,
7284         VK_FORMAT_R64G64_SFLOAT,
7285
7286         // From compatibleFormats192Bit
7287         VK_FORMAT_R64G64B64_UINT,
7288         VK_FORMAT_R64G64B64_SFLOAT,
7289
7290         // From compatibleFormats256Bit
7291         VK_FORMAT_R64G64B64A64_UINT,
7292         VK_FORMAT_R64G64B64A64_SFLOAT,
7293 };
7294
7295 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7296 {
7297         if (allocationKind == ALLOCATION_KIND_DEDICATED)
7298         {
7299                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7300                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
7301                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7302         }
7303
7304         // 2D tests.
7305         {
7306                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7307
7308                 TestParams      params;
7309                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
7310                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
7311                 params.src.image.extent         = defaultExtent;
7312                 params.dst.image.extent         = defaultExtent;
7313                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7314                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7315                 params.allocationKind           = allocationKind;
7316                 params.extensionUse                     = extensionUse;
7317
7318                 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7319                 {
7320                         const VkImageCopy                               testCopy =
7321                         {
7322                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
7323                                 {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
7324                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
7325                                 {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
7326                                 {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
7327                         };
7328
7329                         CopyRegion      imageCopy;
7330                         imageCopy.imageCopy = testCopy;
7331
7332                         params.regions.push_back(imageCopy);
7333                 }
7334
7335                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7336                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7337                 {
7338                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7339                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7340                         {
7341                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7342                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7343                                         continue;
7344
7345                                 CopyColorTestParams     testParams;
7346                                 testParams.params                               = params;
7347                                 testParams.compatibleFormats    = compatibleFormats;
7348
7349                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7350                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7351                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7352                         }
7353                 }
7354
7355                 group->addChild(subGroup.release());
7356         }
7357
7358         // 1D tests.
7359         {
7360                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7361
7362                 TestParams      params;
7363                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
7364                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
7365                 params.src.image.extent         = default1dExtent;
7366                 params.dst.image.extent         = default1dExtent;
7367                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7368                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7369                 params.allocationKind           = allocationKind;
7370                 params.extensionUse                     = extensionUse;
7371
7372                 for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7373                 {
7374                         const VkImageCopy                               testCopy =
7375                         {
7376                                 defaultSourceLayer,                     // VkImageSubresourceLayers     srcSubresource;
7377                                 {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7378                                 defaultSourceLayer,                     // VkImageSubresourceLayers     dstSubresource;
7379                                 {i, 0, 0},                                      // VkOffset3D                           dstOffset;
7380                                 {defaultFourthSize, 1, 1},      // VkExtent3D                           extent;
7381                         };
7382
7383                         CopyRegion      imageCopy;
7384                         imageCopy.imageCopy = testCopy;
7385
7386                         params.regions.push_back(imageCopy);
7387                 }
7388
7389                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7390                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7391                 {
7392                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7393                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7394                         {
7395                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7396                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7397                                         continue;
7398
7399                                 CopyColorTestParams     testParams;
7400                                 testParams.params                               = params;
7401                                 testParams.compatibleFormats    = nullptr;
7402
7403                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7404                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7405                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7406                         }
7407                 }
7408
7409                 group->addChild(subGroup.release());
7410         }
7411
7412         // 3D tests. Note we use smaller dimensions here for performance reasons.
7413         {
7414                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7415
7416                 TestParams      params;
7417                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
7418                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
7419                 params.src.image.extent         = default3dExtent;
7420                 params.dst.image.extent         = default3dExtent;
7421                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7422                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7423                 params.allocationKind           = allocationKind;
7424                 params.extensionUse                     = extensionUse;
7425
7426                 for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7427                 {
7428                         const VkImageCopy                               testCopy =
7429                         {
7430                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     srcSubresource;
7431                                 {0, 0, 0},                                                                                                                      // VkOffset3D                           srcOffset;
7432                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     dstSubresource;
7433                                 {i, defaultFourthSize - i - defaultSixteenthSize, i},                           // VkOffset3D                           dstOffset;
7434                                 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},     // VkExtent3D                           extent;
7435                         };
7436
7437                         CopyRegion      imageCopy;
7438                         imageCopy.imageCopy = testCopy;
7439
7440                         params.regions.push_back(imageCopy);
7441                 }
7442
7443                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7444                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7445                 {
7446                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7447                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7448                         {
7449                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7450                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7451                                         continue;
7452
7453                                 CopyColorTestParams     testParams;
7454                                 testParams.params                               = params;
7455                                 testParams.compatibleFormats    = nullptr;
7456
7457                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7458                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7459                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7460                         }
7461                 }
7462
7463                 group->addChild(subGroup.release());
7464         }
7465 }
7466
7467 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7468 {
7469         tcu::TestContext&               testCtx                         = group->getTestContext();
7470
7471         const VkFormat                  testFormats[][2]        =
7472         {
7473                 // From compatibleFormats8Bit
7474                 {
7475                         VK_FORMAT_R4G4_UNORM_PACK8,
7476                         VK_FORMAT_R8_SRGB
7477                 },
7478                 // From compatibleFormats16Bit
7479                 {
7480                         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7481                         VK_FORMAT_R16_SFLOAT,
7482                 },
7483                 // From compatibleFormats24Bit
7484                 {
7485                         VK_FORMAT_R8G8B8_UNORM,
7486                         VK_FORMAT_B8G8R8_SRGB
7487                 },
7488                 // From compatibleFormats32Bit
7489                 {
7490                         VK_FORMAT_R8G8B8A8_UNORM,
7491                         VK_FORMAT_R32_SFLOAT
7492                 },
7493                 // From compatibleFormats48Bit
7494                 {
7495                         VK_FORMAT_R16G16B16_UNORM,
7496                         VK_FORMAT_R16G16B16_SFLOAT
7497                 },
7498                 // From compatibleFormats64Bit
7499                 {
7500                         VK_FORMAT_R16G16B16A16_UNORM,
7501                         VK_FORMAT_R64_SFLOAT
7502                 },
7503                 // From compatibleFormats96Bit
7504                 {
7505                         VK_FORMAT_R32G32B32_UINT,
7506                         VK_FORMAT_R32G32B32_SFLOAT
7507                 },
7508                 // From compatibleFormats128Bit
7509                 {
7510                         VK_FORMAT_R32G32B32A32_UINT,
7511                         VK_FORMAT_R64G64_SFLOAT
7512                 },
7513                 // From compatibleFormats192Bit
7514                 {
7515                         VK_FORMAT_R64G64B64_UINT,
7516                         VK_FORMAT_R64G64B64_SFLOAT,
7517                 },
7518                 // From compatibleFormats256Bit
7519                 {
7520                         VK_FORMAT_R64G64B64A64_UINT,
7521                         VK_FORMAT_R64G64B64A64_SFLOAT
7522                 }
7523         };
7524
7525         const tcu::UVec2                imageDimensions[]       =
7526         {
7527                 // large pot x small pot
7528                 tcu::UVec2(4096,        4u),
7529                 tcu::UVec2(8192,        4u),
7530                 tcu::UVec2(16384,       4u),
7531                 tcu::UVec2(32768,       4u),
7532
7533                 // large pot x small npot
7534                 tcu::UVec2(4096,        6u),
7535                 tcu::UVec2(8192,        6u),
7536                 tcu::UVec2(16384,       6u),
7537                 tcu::UVec2(32768,       6u),
7538
7539                 // small pot x large pot
7540                 tcu::UVec2(4u, 4096),
7541                 tcu::UVec2(4u, 8192),
7542                 tcu::UVec2(4u, 16384),
7543                 tcu::UVec2(4u, 32768),
7544
7545                 // small npot x large pot
7546                 tcu::UVec2(6u, 4096),
7547                 tcu::UVec2(6u, 8192),
7548                 tcu::UVec2(6u, 16384),
7549                 tcu::UVec2(6u, 32768)
7550         };
7551
7552         const VkImageLayout             copySrcLayouts[]        =
7553         {
7554                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7555                 VK_IMAGE_LAYOUT_GENERAL
7556         };
7557
7558         const VkImageLayout             copyDstLayouts[]        =
7559         {
7560                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7561                 VK_IMAGE_LAYOUT_GENERAL
7562         };
7563
7564         if (allocationKind == ALLOCATION_KIND_DEDICATED)
7565         {
7566                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7567                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7568         }
7569
7570         // Image dimensions
7571         for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
7572         {
7573                 CopyRegion                              copyRegion;
7574                 CopyColorTestParams             testParams;
7575
7576                 const VkExtent3D                extent                  = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
7577
7578                 const VkImageCopy               testCopy                =
7579                 {
7580                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
7581                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
7582                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
7583                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
7584                         extent,                         // VkExtent3D                           extent;
7585                 };
7586
7587                 testParams.params.src.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
7588                 testParams.params.src.image.imageType   = VK_IMAGE_TYPE_2D;
7589                 testParams.params.src.image.extent              = extent;
7590
7591                 testParams.params.dst.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
7592                 testParams.params.dst.image.imageType   = VK_IMAGE_TYPE_2D;
7593                 testParams.params.dst.image.extent              = extent;
7594
7595                 copyRegion.imageCopy                                    = testCopy;
7596                 testParams.params.allocationKind                = allocationKind;
7597                 testParams.params.extensionUse                  = extensionUse;
7598
7599                 testParams.params.regions.push_back(copyRegion);
7600
7601                 const std::string       dimensionStr            = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
7602                                                                                                   + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
7603                 tcu::TestCaseGroup*     imageSizeGroup          = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
7604
7605                 // Compatible formats for copying
7606                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7607                 {
7608                         const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
7609
7610                         testParams.compatibleFormats = compatibleFormats;
7611
7612                         // Source image format
7613                         for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
7614                         {
7615                                 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
7616
7617                                 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
7618                                         continue;
7619
7620                                 const std::string       srcDescription  = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
7621                                 tcu::TestCaseGroup*     srcFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
7622
7623                                 // Destination image format
7624                                 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
7625                                 {
7626                                         testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
7627
7628                                         if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
7629                                                 continue;
7630
7631                                         if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
7632                                                 continue;
7633
7634                                         if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
7635                                         {
7636                                                 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
7637                                                         || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
7638                                                         continue;
7639                                         }
7640
7641                                         const std::string       dstDescription  = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
7642                                         tcu::TestCaseGroup*     dstFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
7643
7644                                         // Source/destionation image layouts
7645                                         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
7646                                         {
7647                                                 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7648
7649                                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
7650                                                 {
7651                                                         testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7652
7653                                                         const std::string       testName        = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
7654                                                         const std::string       description     = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
7655                                                         const TestParams        params          = testParams.params;
7656
7657                                                         dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
7658                                                 }
7659                                         }
7660
7661                                         srcFormatGroup->addChild(dstFormatGroup);
7662                                 }
7663
7664                                 imageSizeGroup->addChild(srcFormatGroup);
7665                         }
7666                 }
7667
7668                 group->addChild(imageSizeGroup);
7669         }
7670 }
7671
7672 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
7673 {
7674         const VkImageLayout copySrcLayouts[]            =
7675         {
7676                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7677                 VK_IMAGE_LAYOUT_GENERAL
7678         };
7679         const VkImageLayout copyDstLayouts[]            =
7680         {
7681                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7682                 VK_IMAGE_LAYOUT_GENERAL
7683         };
7684
7685         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
7686         {
7687                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7688                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
7689                 {
7690                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7691
7692                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
7693                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
7694                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
7695                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
7696                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
7697                 }
7698         }
7699 }
7700
7701 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7702 {
7703         const VkFormat  depthAndStencilFormats[]        =
7704         {
7705                 VK_FORMAT_D16_UNORM,
7706                 VK_FORMAT_X8_D24_UNORM_PACK32,
7707                 VK_FORMAT_D32_SFLOAT,
7708                 VK_FORMAT_S8_UINT,
7709                 VK_FORMAT_D16_UNORM_S8_UINT,
7710                 VK_FORMAT_D24_UNORM_S8_UINT,
7711                 VK_FORMAT_D32_SFLOAT_S8_UINT,
7712         };
7713
7714         // 2D tests.
7715         {
7716                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7717
7718                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7719                 {
7720                         TestParams      params;
7721                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7722                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
7723                         params.src.image.extent                         = defaultExtent;
7724                         params.dst.image.extent                         = defaultExtent;
7725                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7726                         params.dst.image.format                         = params.src.image.format;
7727                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7728                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7729                         params.allocationKind                           = allocationKind;
7730                         params.extensionUse                                     = extensionUse;
7731                         params.separateDepthStencilLayouts      = DE_FALSE;
7732
7733                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7734                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7735
7736                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7737                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7738                         const VkImageSubresourceLayers          defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7739
7740                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7741                         {
7742                                 CopyRegion                      copyRegion;
7743                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7744                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
7745                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
7746
7747                                 if (hasDepth)
7748                                 {
7749                                         const VkImageCopy                               testCopy        =
7750                                         {
7751                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7752                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7753                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7754                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7755                                                 extent,                                         // VkExtent3D                           extent;
7756                                         };
7757
7758                                         copyRegion.imageCopy    = testCopy;
7759                                         params.regions.push_back(copyRegion);
7760                                 }
7761                                 if (hasStencil)
7762                                 {
7763                                         const VkImageCopy                               testCopy        =
7764                                         {
7765                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7766                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7767                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7768                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7769                                                 extent,                                         // VkExtent3D                           extent;
7770                                         };
7771
7772                                         copyRegion.imageCopy    = testCopy;
7773                                         params.regions.push_back(copyRegion);
7774                                 }
7775                         }
7776
7777                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7778                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7779                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7780
7781                         if (hasDepth && hasStencil)
7782                         {
7783                                 params.separateDepthStencilLayouts      = DE_TRUE;
7784                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7785                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7786                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7787
7788                                 // DS Image copy
7789                                 {
7790                                         params.separateDepthStencilLayouts      = DE_FALSE;
7791                                         // Clear previous vkImageCopy elements
7792                                         params.regions.clear();
7793
7794                                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7795                                         {
7796                                                 CopyRegion                      copyRegion;
7797                                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7798                                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
7799                                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
7800
7801                                                 const VkImageCopy                               testCopy        =
7802                                                 {
7803                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     srcSubresource;
7804                                                         srcOffset,                                      // VkOffset3D                           srcOffset;
7805                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     dstSubresource;
7806                                                         dstOffset,                                      // VkOffset3D                           dstOffset;
7807                                                         extent,                                         // VkExtent3D                           extent;
7808                                                 };
7809
7810                                                 copyRegion.imageCopy    = testCopy;
7811                                                 params.regions.push_back(copyRegion);
7812                                         }
7813
7814                                         const std::string testName3             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
7815                                         const std::string description3  = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7816                                         addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7817                                 }
7818                         }
7819                 }
7820
7821                 group->addChild(subGroup.release());
7822         }
7823
7824         // 1D tests.
7825         {
7826                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7827
7828                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7829                 {
7830                         TestParams      params;
7831                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
7832                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
7833                         params.src.image.extent                         = default1dExtent;
7834                         params.dst.image.extent                         = default1dExtent;
7835                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7836                         params.dst.image.format                         = params.src.image.format;
7837                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7838                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7839                         params.allocationKind                           = allocationKind;
7840                         params.extensionUse                                     = extensionUse;
7841
7842                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7843                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7844
7845                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7846                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7847
7848                         for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7849                         {
7850                                 CopyRegion                      copyRegion;
7851                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7852                                 const VkOffset3D        dstOffset       = {i, 0, 0};
7853                                 const VkExtent3D        extent          = {defaultFourthSize, 1, 1};
7854
7855                                 if (hasDepth)
7856                                 {
7857                                         const VkImageCopy                               testCopy        =
7858                                         {
7859                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7860                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7861                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7862                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7863                                                 extent,                                         // VkExtent3D                           extent;
7864                                         };
7865
7866                                         copyRegion.imageCopy    = testCopy;
7867                                         params.regions.push_back(copyRegion);
7868                                 }
7869                                 if (hasStencil)
7870                                 {
7871                                         const VkImageCopy                               testCopy        =
7872                                         {
7873                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7874                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7875                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7876                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7877                                                 extent,                                         // VkExtent3D                           extent;
7878                                         };
7879
7880                                         copyRegion.imageCopy    = testCopy;
7881                                         params.regions.push_back(copyRegion);
7882                                 }
7883                         }
7884
7885                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7886                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7887                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7888
7889                         if (hasDepth && hasStencil)
7890                         {
7891                                 params.separateDepthStencilLayouts      = DE_TRUE;
7892                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7893                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7894                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7895                         }
7896                 }
7897
7898                 group->addChild(subGroup.release());
7899         }
7900
7901         // 3D tests. Note we use smaller dimensions here for performance reasons.
7902         {
7903                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7904
7905                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7906                 {
7907                         TestParams      params;
7908                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
7909                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
7910                         params.src.image.extent                         = default3dExtent;
7911                         params.dst.image.extent                         = default3dExtent;
7912                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7913                         params.dst.image.format                         = params.src.image.format;
7914                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7915                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7916                         params.allocationKind                           = allocationKind;
7917                         params.extensionUse                                     = extensionUse;
7918
7919                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7920                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7921
7922                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7923                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7924
7925                         for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7926                         {
7927                                 CopyRegion                      copyRegion;
7928                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7929                                 const VkOffset3D        dstOffset       = {i, defaultFourthSize - i - defaultSixteenthSize, i};
7930                                 const VkExtent3D        extent          = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
7931
7932                                 if (hasDepth)
7933                                 {
7934                                         const VkImageCopy                               testCopy        =
7935                                         {
7936                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7937                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7938                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7939                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7940                                                 extent,                                         // VkExtent3D                           extent;
7941                                         };
7942
7943                                         copyRegion.imageCopy    = testCopy;
7944                                         params.regions.push_back(copyRegion);
7945                                 }
7946                                 if (hasStencil)
7947                                 {
7948                                         const VkImageCopy                               testCopy        =
7949                                         {
7950                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7951                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7952                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7953                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7954                                                 extent,                                         // VkExtent3D                           extent;
7955                                         };
7956
7957                                         copyRegion.imageCopy    = testCopy;
7958                                         params.regions.push_back(copyRegion);
7959                                 }
7960                         }
7961
7962                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7963                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7964                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7965
7966                         if (hasDepth && hasStencil)
7967                         {
7968                                 params.separateDepthStencilLayouts      = DE_TRUE;
7969                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7970                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7971                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7972                         }
7973                 }
7974
7975                 group->addChild(subGroup.release());
7976         }
7977 }
7978
7979 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7980 {
7981         addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
7982         addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
7983 }
7984
7985 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7986 {
7987         tcu::TestContext& testCtx       = group->getTestContext();
7988
7989         {
7990                 TestParams      params3DTo2D;
7991                 const deUint32  slicesLayers                    = 16u;
7992                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
7993                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7994                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
7995                 params3DTo2D.src.image.extent.depth             = slicesLayers;
7996                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7997                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7998                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
7999                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8000                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
8001                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
8002                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8003                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8004                 params3DTo2D.allocationKind                             = allocationKind;
8005                 params3DTo2D.extensionUse                               = extensionUse;
8006
8007                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8008                 {
8009                         const VkImageSubresourceLayers  sourceLayer     =
8010                         {
8011                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8012                                 0u,                                                     // deUint32                             mipLevel;
8013                                 0u,                                                     // deUint32                             baseArrayLayer;
8014                                 1u                                                      // deUint32                             layerCount;
8015                         };
8016
8017                         const VkImageSubresourceLayers  destinationLayer        =
8018                         {
8019                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8020                                 0u,                                                     // deUint32                             mipLevel;
8021                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8022                                 1u                                                      // deUint32                             layerCount;
8023                         };
8024
8025                         const VkImageCopy                               testCopy        =
8026                         {
8027                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
8028                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           srcOffset;
8029                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
8030                                 {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
8031                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
8032                         };
8033
8034                         CopyRegion      imageCopy;
8035                         imageCopy.imageCopy     = testCopy;
8036
8037                         params3DTo2D.regions.push_back(imageCopy);
8038                 }
8039                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
8040         }
8041
8042         {
8043                 TestParams      params2DTo3D;
8044                 const deUint32  slicesLayers                    = 16u;
8045                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8046                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8047                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8048                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8049                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8050                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8051                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8052                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8053                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8054                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8055                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8056                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8057                 params2DTo3D.allocationKind                             = allocationKind;
8058                 params2DTo3D.extensionUse                               = extensionUse;
8059
8060                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8061                 {
8062                         const VkImageSubresourceLayers  sourceLayer     =
8063                         {
8064                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8065                                 0u,                                                     // deUint32                             mipLevel;
8066                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8067                                 1u                                                      // deUint32                             layerCount;
8068                         };
8069
8070                         const VkImageSubresourceLayers  destinationLayer        =
8071                         {
8072                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8073                                 0u,                                                     // deUint32                             mipLevel;
8074                                 0u,                                                     // deUint32                             baseArrayLayer;
8075                                 1u                                                      // deUint32                             layerCount;
8076                         };
8077
8078                         const VkImageCopy                               testCopy        =
8079                         {
8080                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
8081                                 {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
8082                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
8083                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           dstOffset;
8084                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
8085                         };
8086
8087                         CopyRegion      imageCopy;
8088                         imageCopy.imageCopy     = testCopy;
8089
8090                         params2DTo3D.regions.push_back(imageCopy);
8091                 }
8092
8093                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
8094         }
8095
8096         {
8097                 TestParams      params3DTo2D;
8098                 const deUint32  slicesLayers                    = 16u;
8099                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
8100                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8101                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
8102                 params3DTo2D.src.image.extent.depth             = slicesLayers;
8103                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8104                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8105                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
8106                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8107                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
8108                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
8109                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8110                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8111                 params3DTo2D.allocationKind                             = allocationKind;
8112                 params3DTo2D.extensionUse                               = extensionUse;
8113
8114                 {
8115                         const VkImageSubresourceLayers  sourceLayer     =
8116                         {
8117                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8118                                 0u,                                                     // deUint32                             mipLevel;
8119                                 0u,                                                     // deUint32                             baseArrayLayer;
8120                                 1u                                                      // deUint32                             layerCount;
8121                         };
8122
8123                         const VkImageSubresourceLayers  destinationLayer        =
8124                         {
8125                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8126                                 0u,                                                     // deUint32                             mipLevel;
8127                                 0,                                                      // deUint32                             baseArrayLayer;
8128                                 slicesLayers                            // deUint32                             layerCount;
8129                         };
8130
8131                         const VkImageCopy                               testCopy        =
8132                         {
8133                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8134                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8135                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8136                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8137                                 params3DTo2D.src.image.extent   // VkExtent3D                           extent;
8138                         };
8139
8140                         CopyRegion      imageCopy;
8141                         imageCopy.imageCopy     = testCopy;
8142
8143                         params3DTo2D.regions.push_back(imageCopy);
8144                 }
8145                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
8146         }
8147
8148         {
8149                 TestParams      params2DTo3D;
8150                 const deUint32  slicesLayers                    = 16u;
8151                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8152                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8153                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8154                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8155                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8156                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8157                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8158                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8159                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8160                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8161                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8162                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8163                 params2DTo3D.allocationKind                             = allocationKind;
8164                 params2DTo3D.extensionUse                               = extensionUse;
8165
8166                 {
8167                         const VkImageSubresourceLayers  sourceLayer     =
8168                         {
8169                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8170                                 0u,                                                     // deUint32                             mipLevel;
8171                                 0u,                                                     // deUint32                             baseArrayLayer;
8172                                 slicesLayers                            // deUint32                             layerCount;
8173                         };
8174
8175                         const VkImageSubresourceLayers  destinationLayer        =
8176                         {
8177                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8178                                 0u,                                                     // deUint32                             mipLevel;
8179                                 0u,                                                     // deUint32                             baseArrayLayer;
8180                                 1u                                                      // deUint32                             layerCount;
8181                         };
8182
8183                         const VkImageCopy                               testCopy        =
8184                         {
8185                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8186                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8187                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8188                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8189                                 params2DTo3D.src.image.extent,  // VkExtent3D                           extent;
8190                         };
8191
8192                         CopyRegion      imageCopy;
8193                         imageCopy.imageCopy     = testCopy;
8194
8195                         params2DTo3D.regions.push_back(imageCopy);
8196                 }
8197
8198                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
8199         }
8200
8201         {
8202                 TestParams      params3DTo2D;
8203                 const deUint32  slicesLayers                    = 16u;
8204                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
8205                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8206                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
8207                 params3DTo2D.src.image.extent.depth             = slicesLayers;
8208                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8209                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8210                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
8211                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8212                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
8213                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
8214                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8215                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8216                 params3DTo2D.allocationKind                             = allocationKind;
8217                 params3DTo2D.extensionUse                               = extensionUse;
8218
8219                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
8220                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
8221
8222                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8223                 {
8224                         const VkImageSubresourceLayers  sourceLayer     =
8225                         {
8226                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8227                                 0u,                                                     // deUint32                             mipLevel;
8228                                 0u,                                                     // deUint32                             baseArrayLayer;
8229                                 1u                                                      // deUint32                             layerCount;
8230                         };
8231
8232                         const VkImageSubresourceLayers  destinationLayer        =
8233                         {
8234                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8235                                         0u,                                                             // deUint32                             mipLevel;
8236                                         slicesLayersNdx,                                // deUint32                             baseArrayLayer;
8237                                         1u                                                              // deUint32                             layerCount;
8238                         };
8239
8240
8241                         const VkImageCopy                               testCopy        =
8242                         {
8243                                 sourceLayer,                                                                                                                    // VkImageSubresourceLayers     srcSubresource;
8244                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D                           srcOffset;
8245                                         destinationLayer,                                                                                                       // VkImageSubresourceLayers     dstSubresource;
8246                                         {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                         // VkOffset3D                           dstOffset;
8247                                         {
8248                                                 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
8249                                                 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
8250                                                 1
8251                                         }                                                                                                                                       // VkExtent3D                           extent;
8252                         };
8253
8254                         CopyRegion      imageCopy;
8255                         imageCopy.imageCopy = testCopy;
8256                         params3DTo2D.regions.push_back(imageCopy);
8257                 }
8258                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
8259         }
8260
8261         {
8262                 TestParams      params2DTo3D;
8263                 const deUint32  slicesLayers                    = 16u;
8264                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8265                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8266                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8267                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8268                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8269                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8270                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8271                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8272                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8273                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8274                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8275                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8276                 params2DTo3D.allocationKind                             = allocationKind;
8277                 params2DTo3D.extensionUse                               = extensionUse;
8278
8279                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
8280                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
8281
8282                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8283                 {
8284                         const VkImageSubresourceLayers  sourceLayer     =
8285                         {
8286                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8287                                 0u,                                                     // deUint32                             mipLevel;
8288                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8289                                 1u                                                      // deUint32                             layerCount;
8290                         };
8291
8292                         const VkImageSubresourceLayers  destinationLayer        =
8293                         {
8294                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8295                                 0u,                                                     // deUint32                             mipLevel;
8296                                 0u,                                                     // deUint32                             baseArrayLayer;
8297                                 1u                                                      // deUint32                             layerCount;
8298                         };
8299
8300                         const VkImageCopy                               testCopy        =
8301                         {
8302                                 sourceLayer,                                                                                                                            // VkImageSubresourceLayers     srcSubresource;
8303                                 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                                         // VkOffset3D                           srcOffset;
8304                                 destinationLayer,                                                                                                                       // VkImageSubresourceLayers     dstSubresource;
8305                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},       // VkOffset3D                           dstOffset;
8306                                 {
8307                                         defaultHalfExtent.width - regionWidth*slicesLayersNdx,
8308                                         defaultHalfExtent.height - regionHeight*slicesLayersNdx,
8309                                         1
8310                                 }                                                                                                                                                       // VkExtent3D                           extent;
8311                         };
8312
8313                         CopyRegion      imageCopy;
8314                         imageCopy.imageCopy     = testCopy;
8315
8316                         params2DTo3D.regions.push_back(imageCopy);
8317                 }
8318
8319                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
8320         }
8321 }
8322
8323 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8324 {
8325         tcu::TestContext& testCtx       = group->getTestContext();
8326
8327         {
8328                 TestParams      paramsCubeToArray;
8329                 const deUint32  arrayLayers                                     = 6u;
8330                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8331                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8332                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8333                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8334                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8335                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8336                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8337                 paramsCubeToArray.dst.image.createFlags         = 0;
8338                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8339                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8340                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8341                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8342                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8343                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8344                 paramsCubeToArray.allocationKind                        = allocationKind;
8345                 paramsCubeToArray.extensionUse                          = extensionUse;
8346
8347                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8348                 {
8349                         const VkImageSubresourceLayers  sourceLayer     =
8350                                 {
8351                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8352                                         0u,                                                     // deUint32                             mipLevel;
8353                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8354                                         1u                                                      // deUint32                             layerCount;
8355                                 };
8356
8357                         const VkImageSubresourceLayers  destinationLayer        =
8358                                 {
8359                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8360                                         0u,                                                     // deUint32                             mipLevel;
8361                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8362                                         1u                                                      // deUint32                             layerCount;
8363                                 };
8364
8365                         const VkImageCopy                               testCopy        =
8366                                 {
8367                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8368                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8369                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8370                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8371                                         defaultHalfExtent                               // VkExtent3D                           extent;
8372                                 };
8373
8374                         CopyRegion      imageCopy;
8375                         imageCopy.imageCopy     = testCopy;
8376
8377                         paramsCubeToArray.regions.push_back(imageCopy);
8378                 }
8379
8380                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
8381         }
8382
8383         {
8384                 TestParams      paramsCubeToArray;
8385                 const deUint32  arrayLayers                                     = 6u;
8386                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8387                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8388                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8389                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8390                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8391                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8392                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8393                 paramsCubeToArray.dst.image.createFlags         = 0;
8394                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8395                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8396                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8397                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8398                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8399                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8400                 paramsCubeToArray.allocationKind                        = allocationKind;
8401                 paramsCubeToArray.extensionUse                          = extensionUse;
8402
8403                 {
8404                         const VkImageSubresourceLayers  sourceLayer     =
8405                                 {
8406                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8407                                         0u,                                                     // deUint32                             mipLevel;
8408                                         0u,                                                     // deUint32                             baseArrayLayer;
8409                                         arrayLayers                                     // deUint32                             layerCount;
8410                                 };
8411
8412                         const VkImageSubresourceLayers  destinationLayer        =
8413                                 {
8414                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8415                                         0u,                                                     // deUint32                             mipLevel;
8416                                         0u,                                                     // deUint32                             baseArrayLayer;
8417                                         arrayLayers                                     // deUint32                             layerCount;
8418                                 };
8419
8420                         const VkImageCopy                               testCopy        =
8421                                 {
8422                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8423                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8424                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8425                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8426                                         defaultHalfExtent                       // VkExtent3D                           extent;
8427                                 };
8428
8429                         CopyRegion      imageCopy;
8430                         imageCopy.imageCopy     = testCopy;
8431
8432                         paramsCubeToArray.regions.push_back(imageCopy);
8433                 }
8434
8435                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
8436         }
8437
8438         {
8439                 TestParams      paramsArrayToCube;
8440                 const deUint32  arrayLayers                                     = 6u;
8441                 paramsArrayToCube.src.image.createFlags         = 0;
8442                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
8443                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8444                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
8445                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
8446                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8447                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8448                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8449                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8450                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8451                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
8452                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
8453                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8454                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8455                 paramsArrayToCube.allocationKind                        = allocationKind;
8456                 paramsArrayToCube.extensionUse                          = extensionUse;
8457
8458                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8459                 {
8460                         const VkImageSubresourceLayers  sourceLayer     =
8461                                 {
8462                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8463                                         0u,                                                     // deUint32                             mipLevel;
8464                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8465                                         1u                                                      // deUint32                             layerCount;
8466                                 };
8467
8468                         const VkImageSubresourceLayers  destinationLayer =
8469                                 {
8470                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8471                                         0u,                                                     // deUint32                             mipLevel;
8472                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8473                                         1u                                                      // deUint32                             layerCount;
8474                                 };
8475
8476                         const VkImageCopy                               testCopy =
8477                                 {
8478                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8479                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8480                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8481                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8482                                         defaultHalfExtent                       // VkExtent3D                           extent;
8483                                 };
8484
8485                         CopyRegion      imageCopy;
8486                         imageCopy.imageCopy     = testCopy;
8487
8488                         paramsArrayToCube.regions.push_back(imageCopy);
8489                 }
8490
8491                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
8492         }
8493
8494         {
8495                 TestParams      paramsArrayToCube;
8496                 const deUint32  arrayLayers                                     = 6u;
8497                 paramsArrayToCube.src.image.createFlags         = 0;
8498                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
8499                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8500                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
8501                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
8502                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8503                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8504                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8505                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8506                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8507                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
8508                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
8509                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8510                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8511                 paramsArrayToCube.allocationKind                        = allocationKind;
8512                 paramsArrayToCube.extensionUse                          = extensionUse;
8513
8514                 {
8515                         const VkImageSubresourceLayers sourceLayer =
8516                                 {
8517                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8518                                         0u,                                                             // deUint32                             mipLevel;
8519                                         0u,                                                             // deUint32                             baseArrayLayer;
8520                                         arrayLayers                                             // deUint32                             layerCount;
8521                                 };
8522
8523                         const VkImageSubresourceLayers destinationLayer =
8524                                 {
8525                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8526                                         0u,                                                             // deUint32                             mipLevel;
8527                                         0u,                                                             // deUint32                             baseArrayLayer;
8528                                         arrayLayers                                             // deUint32                             layerCount;
8529                                 };
8530
8531                         const VkImageCopy                               testCopy =
8532                                 {
8533                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8534                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8535                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8536                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8537                                         defaultHalfExtent                               // VkExtent3D                           extent;
8538                                 };
8539
8540                         CopyRegion imageCopy;
8541                         imageCopy.imageCopy = testCopy;
8542
8543                         paramsArrayToCube.regions.push_back(imageCopy);
8544                 }
8545
8546                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
8547         }
8548
8549         {
8550                 TestParams      paramsCubeToArray;
8551                 const deUint32  arrayLayers                                     = 6u;
8552                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8553                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8554                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8555                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8556                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8557                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8558                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8559                 paramsCubeToArray.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8560                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8561                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8562                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8563                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8564                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8565                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8566                 paramsCubeToArray.allocationKind                        = allocationKind;
8567                 paramsCubeToArray.extensionUse                          = extensionUse;
8568
8569                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8570                 {
8571                         const VkImageSubresourceLayers  sourceLayer     =
8572                                 {
8573                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8574                                         0u,                                                     // deUint32                             mipLevel;
8575                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8576                                         1u                                                      // deUint32                             layerCount;
8577                                 };
8578
8579                         const VkImageSubresourceLayers  destinationLayer        =
8580                                 {
8581                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8582                                         0u,                                                     // deUint32                             mipLevel;
8583                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8584                                         1u                                                      // deUint32                             layerCount;
8585                                 };
8586
8587                         const VkImageCopy                               testCopy        =
8588                                 {
8589                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8590                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8591                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8592                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8593                                         defaultHalfExtent                               // VkExtent3D                           extent;
8594                                 };
8595
8596                         CopyRegion      imageCopy;
8597                         imageCopy.imageCopy     = testCopy;
8598
8599                         paramsCubeToArray.regions.push_back(imageCopy);
8600                 }
8601
8602                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
8603         }
8604
8605         {
8606                 TestParams      paramsCubeToCube;
8607                 const deUint32  arrayLayers                                     = 6u;
8608                 paramsCubeToCube.src.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8609                 paramsCubeToCube.src.image.imageType            = VK_IMAGE_TYPE_2D;
8610                 paramsCubeToCube.src.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
8611                 paramsCubeToCube.src.image.extent                       = defaultHalfExtent;
8612                 paramsCubeToCube.src.image.extent.depth         = arrayLayers;
8613                 paramsCubeToCube.src.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
8614                 paramsCubeToCube.src.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8615                 paramsCubeToCube.dst.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8616                 paramsCubeToCube.dst.image.imageType            = VK_IMAGE_TYPE_2D;
8617                 paramsCubeToCube.dst.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
8618                 paramsCubeToCube.dst.image.extent                       = defaultHalfExtent;
8619                 paramsCubeToCube.dst.image.extent.depth         = arrayLayers;
8620                 paramsCubeToCube.dst.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
8621                 paramsCubeToCube.dst.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8622                 paramsCubeToCube.allocationKind                         = allocationKind;
8623                 paramsCubeToCube.extensionUse                           = extensionUse;
8624
8625                 {
8626                         const VkImageSubresourceLayers  sourceLayer     =
8627                                 {
8628                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8629                                         0u,                                                     // deUint32                             mipLevel;
8630                                         0u,                                                     // deUint32                             baseArrayLayer;
8631                                         arrayLayers                                     // deUint32                             layerCount;
8632                                 };
8633
8634                         const VkImageSubresourceLayers  destinationLayer        =
8635                                 {
8636                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8637                                         0u,                                                     // deUint32                             mipLevel;
8638                                         0u,                                                     // deUint32                             baseArrayLayer;
8639                                         arrayLayers                                     // deUint32                             layerCount;
8640                                 };
8641
8642                         const VkImageCopy                               testCopy        =
8643                                 {
8644                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8645                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8646                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8647                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8648                                         defaultHalfExtent                       // VkExtent3D                           extent;
8649                                 };
8650
8651                         CopyRegion      imageCopy;
8652                         imageCopy.imageCopy     = testCopy;
8653
8654                         paramsCubeToCube.regions.push_back(imageCopy);
8655                 }
8656
8657                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
8658         }
8659 }
8660
8661 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8662 {
8663         tcu::TestContext& testCtx       = group->getTestContext();
8664
8665         {
8666                 TestParams      paramsArrayToArray;
8667                 const deUint32  arrayLayers                                     = 16u;
8668                 paramsArrayToArray.src.image.imageType          = VK_IMAGE_TYPE_2D;
8669                 paramsArrayToArray.src.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
8670                 paramsArrayToArray.src.image.extent                     = defaultHalfExtent;
8671                 paramsArrayToArray.src.image.extent.depth       = arrayLayers;
8672                 paramsArrayToArray.src.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
8673                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8674                 paramsArrayToArray.dst.image.imageType          = VK_IMAGE_TYPE_2D;
8675                 paramsArrayToArray.dst.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
8676                 paramsArrayToArray.dst.image.extent                     = defaultHalfExtent;
8677                 paramsArrayToArray.dst.image.extent.depth       = arrayLayers;
8678                 paramsArrayToArray.dst.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
8679                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8680                 paramsArrayToArray.allocationKind                       = allocationKind;
8681                 paramsArrayToArray.extensionUse                         = extensionUse;
8682
8683                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8684                 {
8685                         const VkImageSubresourceLayers  sourceLayer     =
8686                                         {
8687                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8688                                                         0u,                                                     // deUint32                             mipLevel;
8689                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8690                                                         1u                                                      // deUint32                             layerCount;
8691                                         };
8692
8693                         const VkImageSubresourceLayers  destinationLayer =
8694                                         {
8695                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8696                                                         0u,                                                     // deUint32                             mipLevel;
8697                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8698                                                         1u                                                      // deUint32                             layerCount;
8699                                         };
8700
8701                         const VkImageCopy                               testCopy =
8702                                         {
8703                                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8704                                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8705                                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8706                                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8707                                                         defaultHalfExtent                       // VkExtent3D                           extent;
8708                                         };
8709
8710                         CopyRegion      imageCopy;
8711                         imageCopy.imageCopy     = testCopy;
8712
8713                         paramsArrayToArray.regions.push_back(imageCopy);
8714                 }
8715
8716                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
8717         }
8718
8719         {
8720                 TestParams      paramsArrayToArray;
8721                 const deUint32  arrayLayers                                             = 16u;
8722                 paramsArrayToArray.src.image.imageType                  = VK_IMAGE_TYPE_2D;
8723                 paramsArrayToArray.src.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
8724                 paramsArrayToArray.src.image.extent                             = defaultHalfExtent;
8725                 paramsArrayToArray.src.image.extent.depth               = arrayLayers;
8726                 paramsArrayToArray.src.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8727                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8728                 paramsArrayToArray.dst.image.imageType                  = VK_IMAGE_TYPE_2D;
8729                 paramsArrayToArray.dst.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
8730                 paramsArrayToArray.dst.image.extent                             = defaultHalfExtent;
8731                 paramsArrayToArray.dst.image.extent.depth               = arrayLayers;
8732                 paramsArrayToArray.dst.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8733                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8734                 paramsArrayToArray.allocationKind                               = allocationKind;
8735                 paramsArrayToArray.extensionUse                                 = extensionUse;
8736
8737                 {
8738                         const VkImageSubresourceLayers sourceLayer =
8739                                         {
8740                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8741                                                         0u,                                                             // deUint32                             mipLevel;
8742                                                         0u,                                                             // deUint32                             baseArrayLayer;
8743                                                         arrayLayers                                             // deUint32                             layerCount;
8744                                         };
8745
8746                         const VkImageSubresourceLayers destinationLayer =
8747                                         {
8748                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8749                                                         0u,                                                             // deUint32                             mipLevel;
8750                                                         0u,                                                             // deUint32                             baseArrayLayer;
8751                                                         arrayLayers                                             // deUint32                             layerCount;
8752                                         };
8753
8754                         const VkImageCopy                               testCopy =
8755                                         {
8756                                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8757                                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8758                                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8759                                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8760                                                         defaultHalfExtent                               // VkExtent3D                           extent;
8761                                         };
8762
8763                         CopyRegion imageCopy;
8764                         imageCopy.imageCopy = testCopy;
8765
8766                         paramsArrayToArray.regions.push_back(imageCopy);
8767                 }
8768
8769                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
8770         }
8771
8772         {
8773                 TestParams      paramsArrayToArray;
8774                 const deUint32  arrayLayers                                             = 16u;
8775                 paramsArrayToArray.src.image.imageType                  = VK_IMAGE_TYPE_2D;
8776                 paramsArrayToArray.src.image.extent                             = defaultHalfExtent;
8777                 paramsArrayToArray.src.image.extent.depth               = arrayLayers;
8778                 paramsArrayToArray.src.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8779                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8780                 paramsArrayToArray.dst.image.imageType                  = VK_IMAGE_TYPE_2D;
8781                 paramsArrayToArray.dst.image.extent                             = defaultHalfExtent;
8782                 paramsArrayToArray.dst.image.extent.depth               = arrayLayers;
8783                 paramsArrayToArray.dst.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8784                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8785                 paramsArrayToArray.allocationKind                               = allocationKind;
8786                 paramsArrayToArray.extensionUse                                 = extensionUse;
8787                 paramsArrayToArray.mipLevels                                    = deLog2Floor32(deMinu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
8788
8789                 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
8790                 {
8791                         const VkImageSubresourceLayers sourceLayer =
8792                         {
8793                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8794                                 mipLevelNdx,                                    // deUint32                             mipLevel;
8795                                 0u,                                                             // deUint32                             baseArrayLayer;
8796                                 arrayLayers                                             // deUint32                             layerCount;
8797                         };
8798
8799                         const VkImageSubresourceLayers destinationLayer =
8800                         {
8801                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8802                                 mipLevelNdx,                                    // deUint32                             mipLevel;
8803                                 0u,                                                             // deUint32                             baseArrayLayer;
8804                                 arrayLayers                                             // deUint32                             layerCount;
8805                         };
8806
8807                         const VkExtent3D extent =
8808                         {
8809                                 (deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),             // deUint32    width;
8810                                 (deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1),    // deUint32    height;
8811                                 1u,                                                                                                                             // deUint32    depth;
8812                         };
8813
8814                         const VkImageCopy                               testCopy =
8815                         {
8816                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8817                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8818                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8819                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8820                                 extent                                                  // VkExtent3D                           extent;
8821                         };
8822
8823                         CopyRegion imageCopy;
8824                         imageCopy.imageCopy = testCopy;
8825
8826                         paramsArrayToArray.regions.push_back(imageCopy);
8827                 }
8828
8829                 VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
8830
8831                 for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
8832                 {
8833                         paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
8834                         paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
8835                         for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
8836                         {
8837                                 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
8838                                 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
8839                         }
8840                         std::ostringstream testName;
8841                         const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
8842                         testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
8843                         group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
8844                 }
8845         }
8846 };
8847
8848 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8849 {
8850         addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
8851         addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
8852         addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
8853         addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
8854         addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
8855         addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
8856 }
8857
8858 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8859 {
8860         tcu::TestContext& testCtx       = group->getTestContext();
8861
8862         {
8863                 TestParams      params;
8864                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8865                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8866                 params.src.image.extent                         = defaultExtent;
8867                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8868                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8869                 params.dst.buffer.size                          = defaultSize * defaultSize;
8870                 params.allocationKind                           = allocationKind;
8871                 params.extensionUse                                     = extensionUse;
8872
8873                 const VkBufferImageCopy bufferImageCopy =
8874                 {
8875                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
8876                         0u,                                                                                     // deUint32                                     bufferRowLength;
8877                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8878                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8879                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
8880                         defaultExtent                                                           // VkExtent3D                           imageExtent;
8881                 };
8882                 CopyRegion      copyRegion;
8883                 copyRegion.bufferImageCopy      = bufferImageCopy;
8884
8885                 params.regions.push_back(copyRegion);
8886
8887                 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
8888         }
8889
8890         {
8891                 TestParams      params;
8892                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8893                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8894                 params.src.image.extent                         = defaultExtent;
8895                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8896                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8897                 params.dst.buffer.size                          = defaultSize * defaultSize;
8898                 params.allocationKind                           = allocationKind;
8899                 params.extensionUse                                     = extensionUse;
8900
8901                 const VkBufferImageCopy bufferImageCopy =
8902                 {
8903                         defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
8904                         0u,                                                                                     // deUint32                                     bufferRowLength;
8905                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8906                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8907                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8908                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8909                 };
8910                 CopyRegion      copyRegion;
8911                 copyRegion.bufferImageCopy      = bufferImageCopy;
8912
8913                 params.regions.push_back(copyRegion);
8914
8915                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
8916         }
8917
8918         {
8919                 TestParams      params;
8920                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8921                 params.src.image.format                         = VK_FORMAT_R8_UNORM;
8922                 params.src.image.extent                         = defaultExtent;
8923                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8924                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8925                 params.dst.buffer.size                          = defaultSize * defaultSize;
8926                 params.allocationKind                           = allocationKind;
8927                 params.extensionUse                                     = extensionUse;
8928
8929                 const VkBufferImageCopy bufferImageCopy =
8930                 {
8931                         defaultSize * defaultHalfSize + 1u,             // VkDeviceSize                         bufferOffset;
8932                         0u,                                                                                     // deUint32                                     bufferRowLength;
8933                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8934                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8935                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8936                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8937                 };
8938                 CopyRegion      copyRegion;
8939                 copyRegion.bufferImageCopy      = bufferImageCopy;
8940
8941                 params.regions.push_back(copyRegion);
8942
8943                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
8944         }
8945
8946         {
8947                 TestParams      params;
8948                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8949                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8950                 params.src.image.extent                         = defaultExtent;
8951                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8952                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8953                 params.dst.buffer.size                          = defaultSize * defaultSize;
8954                 params.allocationKind                           = allocationKind;
8955                 params.extensionUse                                     = extensionUse;
8956
8957                 const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
8958                 const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
8959                 const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
8960                 deUint32                        divisor         = 1;
8961                 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
8962                 {
8963                         const deUint32                  bufferRowLength         = defaultFourthSize;
8964                         const deUint32                  bufferImageHeight       = defaultFourthSize;
8965                         const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
8966                         DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
8967                         DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
8968                         DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
8969
8970                         CopyRegion                              region;
8971                         const VkBufferImageCopy bufferImageCopy         =
8972                         {
8973                                 offset,                                         // VkDeviceSize                         bufferOffset;
8974                                 bufferRowLength,                        // deUint32                                     bufferRowLength;
8975                                 bufferImageHeight,                      // deUint32                                     bufferImageHeight;
8976                                 defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
8977                                 {0, 0, 0},                                      // VkOffset3D                           imageOffset;
8978                                 imageExtent                                     // VkExtent3D                           imageExtent;
8979                         };
8980                         region.bufferImageCopy  = bufferImageCopy;
8981                         params.regions.push_back(region);
8982                 }
8983
8984                 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
8985         }
8986
8987         {
8988                 TestParams                              params;
8989                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8990                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8991                 params.src.image.extent                         = defaultExtent;
8992                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8993                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8994                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
8995                 params.allocationKind                           = allocationKind;
8996                 params.extensionUse                                     = extensionUse;
8997
8998                 const VkBufferImageCopy bufferImageCopy =
8999                 {
9000                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
9001                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9002                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9003                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9004                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9005                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9006                 };
9007                 CopyRegion                              copyRegion;
9008                 copyRegion.bufferImageCopy      = bufferImageCopy;
9009
9010                 params.regions.push_back(copyRegion);
9011
9012                 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
9013         }
9014
9015         {
9016                 TestParams                              params;
9017                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9018                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9019                 params.src.image.extent                         = defaultExtent;
9020                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9021                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9022                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9023                 params.allocationKind                           = allocationKind;
9024                 params.extensionUse                                     = extensionUse;
9025
9026                 const VkBufferImageCopy bufferImageCopy =
9027                 {
9028                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9029                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9030                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9031                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9032                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9033                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9034                 };
9035                 CopyRegion                              copyRegion;
9036                 copyRegion.bufferImageCopy      = bufferImageCopy;
9037
9038                 params.regions.push_back(copyRegion);
9039
9040                 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));
9041         }
9042
9043         {
9044                 TestParams                              params;
9045                 deUint32                                arrayLayers = 16u;
9046                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9047                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9048                 params.src.image.extent                         = defaultHalfExtent;
9049                 params.src.image.extent.depth           = arrayLayers;
9050                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9051                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9052                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9053                 params.allocationKind                           = allocationKind;
9054                 params.extensionUse                                     = extensionUse;
9055
9056                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9057                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9058                 {
9059                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9060                         const VkBufferImageCopy bufferImageCopy =
9061                                 {
9062                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9063                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
9064                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
9065                                         {
9066                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9067                                                 0u,                                                                                             // deUint32                             mipLevel;
9068                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9069                                                 1u,                                                                                             // deUint32                             layerCount;
9070                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9071                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9072                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9073                                 };
9074                         CopyRegion copyRegion;
9075                         copyRegion.bufferImageCopy = bufferImageCopy;
9076
9077                         params.regions.push_back(copyRegion);
9078                 }
9079                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
9080         }
9081
9082         {
9083                 TestParams                              params;
9084                 deUint32                                arrayLayers = 16u;
9085                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9086                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9087                 params.src.image.extent                         = defaultHalfExtent;
9088                 params.src.image.extent.depth           = arrayLayers;
9089                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9090                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9091                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9092                 params.allocationKind                           = allocationKind;
9093                 params.extensionUse                                     = extensionUse;
9094
9095                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9096                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9097                 {
9098                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9099                         const VkBufferImageCopy bufferImageCopy =
9100                                 {
9101                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9102                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
9103                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
9104                                         {
9105                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9106                                                 0u,                                                                                             // deUint32                             mipLevel;
9107                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9108                                                 1u,                                                                                             // deUint32                             layerCount;
9109                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9110                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9111                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9112                                 };
9113                         CopyRegion copyRegion;
9114                         copyRegion.bufferImageCopy = bufferImageCopy;
9115
9116                         params.regions.push_back(copyRegion);
9117                 }
9118                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
9119         }
9120 }
9121
9122 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9123 {
9124         tcu::TestContext& testCtx = group->getTestContext();
9125
9126         const struct
9127         {
9128                 const char*             name;
9129                 const VkFormat  format;
9130         } depthAndStencilFormats[] =
9131         {
9132                 { "d16_unorm",                          VK_FORMAT_D16_UNORM                             },
9133                 { "x8_d24_unorm_pack32",        VK_FORMAT_X8_D24_UNORM_PACK32   },
9134                 { "d32_sfloat",                         VK_FORMAT_D32_SFLOAT                    },
9135                 { "d16_unorm_s8_uint",          VK_FORMAT_D16_UNORM_S8_UINT             },
9136                 { "d24_unorm_s8_uint",          VK_FORMAT_D24_UNORM_S8_UINT             },
9137                 { "d32_sfloat_s8_uint",         VK_FORMAT_D32_SFLOAT_S8_UINT    }
9138         };
9139
9140         const VkImageSubresourceLayers  depthSourceLayer                =
9141         {
9142                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
9143                 0u,                                                     // deUint32                             mipLevel;
9144                 0u,                                                     // deUint32                             baseArrayLayer;
9145                 1u,                                                     // deUint32                             layerCount;
9146         };
9147
9148         const VkBufferImageCopy                 bufferDepthCopy                 =
9149         {
9150                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
9151                 0u,                                                                                     // deUint32                                     bufferRowLength;
9152                 0u,                                                                                     // deUint32                                     bufferImageHeight;
9153                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
9154                 {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
9155                 defaultExtent                                                           // VkExtent3D                           imageExtent;
9156         };
9157
9158         const VkBufferImageCopy                 bufferDepthCopyOffset   =
9159         {
9160                 32,                                                                                     // VkDeviceSize                         bufferOffset;
9161                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9162                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9163                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
9164                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9165                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9166         };
9167
9168         const VkImageSubresourceLayers  stencilSourceLayer              =
9169         {
9170                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
9171                 0u,                                                             // deUint32                             mipLevel;
9172                 0u,                                                             // deUint32                             baseArrayLayer;
9173                 1u,                                                             // deUint32                             layerCount;
9174         };
9175
9176         const VkBufferImageCopy                 bufferStencilCopy               =
9177         {
9178                 0u,                                     // VkDeviceSize                         bufferOffset;
9179                 0u,                                     // deUint32                                     bufferRowLength;
9180                 0u,                                     // deUint32                                     bufferImageHeight;
9181                 stencilSourceLayer,     // VkImageSubresourceLayers     imageSubresource;
9182                 {0, 0, 0},                      // VkOffset3D                           imageOffset;
9183                 defaultExtent           // VkExtent3D                           imageExtent;
9184         };
9185
9186     const VkBufferImageCopy                     bufferStencilCopyOffset =
9187         {
9188                 32,                                                                                     // VkDeviceSize                         bufferOffset;
9189                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9190                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9191                 stencilSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9192                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9193                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9194         };
9195
9196     const bool                                          useOffset[]                             = {false, true};
9197
9198         // Note: Depth stencil tests I want to do
9199         // Formats: D16, D24S8, D32FS8
9200         // Test writing each component with separate CopyBufferToImage commands
9201         // Test writing both components in one CopyBufferToImage command
9202         // Swap order of writes of Depth & Stencil
9203         // whole surface, subimages?
9204         // Similar tests as BufferToImage?
9205         for (const auto config : depthAndStencilFormats)
9206                 for (const auto offset : useOffset)
9207                 {
9208                         // TODO: Check that this format is supported before creating tests?
9209                         //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
9210
9211                         CopyRegion                                      copyDepthRegion;
9212                         CopyRegion                                      copyStencilRegion;
9213                         TestParams                                      params;
9214                         const tcu::TextureFormat        format          = mapVkFormat(config.format);
9215                         const bool                                      hasDepth        = tcu::hasDepthComponent(format.order);
9216                         const bool                                      hasStencil      = tcu::hasStencilComponent(format.order);
9217                         std::string                                     description     = config.name;
9218
9219                         if (offset)
9220                         {
9221                                 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
9222                                 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
9223                                 description = "buffer_offset_" + description;
9224                                 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9225                         }
9226                         else
9227                         {
9228                                 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
9229                                 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
9230                                 params.src.buffer.size = defaultSize * defaultSize;
9231                         }
9232
9233                         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9234                         params.dst.image.format = config.format;
9235                         params.dst.image.extent = defaultExtent;
9236                         params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9237                         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9238                         params.allocationKind = allocationKind;
9239                         params.extensionUse = extensionUse;
9240
9241                         if (hasDepth && hasStencil)
9242                         {
9243                                 params.singleCommand = DE_TRUE;
9244
9245                                 params.regions.push_back(copyDepthRegion);
9246                                 params.regions.push_back(copyStencilRegion);
9247
9248                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
9249
9250                                 params.singleCommand = DE_FALSE;
9251
9252                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
9253
9254                                 params.regions.clear();
9255                                 params.regions.push_back(copyStencilRegion);
9256                                 params.regions.push_back(copyDepthRegion);
9257
9258                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
9259
9260                                 params.singleCommand = DE_TRUE;
9261                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
9262                         }
9263
9264                         if (hasStencil)
9265                         {
9266                                 params.regions.clear();
9267                                 params.regions.push_back(copyStencilRegion);
9268
9269                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
9270                         }
9271
9272                         if (hasDepth)
9273                         {
9274                                 params.regions.clear();
9275                                 params.regions.push_back(copyDepthRegion);
9276
9277                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
9278                         }
9279                 }
9280 }
9281
9282 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9283 {
9284         tcu::TestContext& testCtx       = group->getTestContext();
9285
9286         {
9287                 TestParams      params;
9288                 params.src.buffer.size                          = defaultSize * defaultSize;
9289                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9290                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
9291                 params.dst.image.extent                         = defaultExtent;
9292                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9293                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9294                 params.allocationKind                           = allocationKind;
9295                 params.extensionUse                                     = extensionUse;
9296
9297                 const VkBufferImageCopy bufferImageCopy =
9298                 {
9299                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
9300                         0u,                                                                                     // deUint32                                     bufferRowLength;
9301                         0u,                                                                                     // deUint32                                     bufferImageHeight;
9302                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9303                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
9304                         defaultExtent                                                           // VkExtent3D                           imageExtent;
9305                 };
9306                 CopyRegion      copyRegion;
9307                 copyRegion.bufferImageCopy      = bufferImageCopy;
9308
9309                 params.regions.push_back(copyRegion);
9310
9311                 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
9312         }
9313
9314         {
9315                 TestParams      params;
9316                 params.src.buffer.size                          = defaultSize * defaultSize;
9317                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9318                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9319                 params.dst.image.extent                         = defaultExtent;
9320                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9321                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9322                 params.allocationKind                           = allocationKind;
9323                 params.extensionUse                                     = extensionUse;
9324
9325                 CopyRegion      region;
9326                 deUint32        divisor = 1;
9327                 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
9328                 {
9329                         const VkBufferImageCopy bufferImageCopy =
9330                         {
9331                                 0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
9332                                 0u,                                                                                                                             // deUint32                                     bufferRowLength;
9333                                 0u,                                                                                                                             // deUint32                                     bufferImageHeight;
9334                                 defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
9335                                 {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
9336                                 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
9337                         };
9338                         region.bufferImageCopy  = bufferImageCopy;
9339                         params.regions.push_back(region);
9340                 }
9341
9342                 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
9343         }
9344
9345         {
9346                 TestParams      params;
9347                 params.src.buffer.size                          = defaultSize * defaultSize;
9348                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9349                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9350                 params.dst.image.extent                         = defaultExtent;
9351                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9352                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9353                 params.allocationKind                           = allocationKind;
9354                 params.extensionUse                                     = extensionUse;
9355
9356                 const VkBufferImageCopy bufferImageCopy =
9357                 {
9358                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9359                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9360                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9361                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9362                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9363                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9364                 };
9365                 CopyRegion      copyRegion;
9366                 copyRegion.bufferImageCopy      = bufferImageCopy;
9367
9368                 params.regions.push_back(copyRegion);
9369
9370                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
9371         }
9372
9373         {
9374                 TestParams      params;
9375                 params.src.buffer.size                          = defaultSize * defaultSize;
9376                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9377                 params.dst.image.format                         = VK_FORMAT_R8_UNORM;
9378                 params.dst.image.extent                         = defaultExtent;
9379                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9380                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9381                 params.allocationKind                           = allocationKind;
9382                 params.extensionUse                                     = extensionUse;
9383
9384                 const VkBufferImageCopy bufferImageCopy =
9385                 {
9386                         defaultFourthSize + 1u,                                         // VkDeviceSize                         bufferOffset;
9387                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9388                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9389                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9390                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9391                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9392                 };
9393                 CopyRegion      copyRegion;
9394                 copyRegion.bufferImageCopy      = bufferImageCopy;
9395
9396                 params.regions.push_back(copyRegion);
9397
9398                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
9399         }
9400
9401         {
9402                 TestParams                              params;
9403                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9404                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9405                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9406                 params.dst.image.extent                         = defaultExtent;
9407                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9408                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9409                 params.allocationKind                           = allocationKind;
9410                 params.extensionUse                                     = extensionUse;
9411
9412                 const VkBufferImageCopy bufferImageCopy =
9413                 {
9414                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
9415                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9416                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9417                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9418                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9419                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9420                 };
9421                 CopyRegion                              copyRegion;
9422                 copyRegion.bufferImageCopy      = bufferImageCopy;
9423
9424                 params.regions.push_back(copyRegion);
9425
9426                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
9427         }
9428
9429         {
9430                 TestParams                              params;
9431                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9432                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9433                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9434                 params.dst.image.extent                         = defaultExtent;
9435                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9436                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9437                 params.allocationKind                           = allocationKind;
9438                 params.extensionUse                                     = extensionUse;
9439
9440                 const VkBufferImageCopy bufferImageCopy =
9441                 {
9442                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9443                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9444                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9445                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9446                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9447                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9448                 };
9449                 CopyRegion                              copyRegion;
9450                 copyRegion.bufferImageCopy      = bufferImageCopy;
9451
9452                 params.regions.push_back(copyRegion);
9453
9454                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
9455         }
9456
9457         {
9458                 TestParams                              params;
9459                 deUint32                                arrayLayers = 16u;
9460                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9461                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9462                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9463                 params.dst.image.extent                         = defaultHalfExtent;
9464                 params.dst.image.extent.depth           = arrayLayers;
9465                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9466                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9467                 params.allocationKind                           = allocationKind;
9468                 params.extensionUse                                     = extensionUse;
9469
9470                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9471                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9472                 {
9473                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9474                         const VkBufferImageCopy bufferImageCopy =
9475                                 {
9476                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9477                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
9478                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
9479                                         {
9480                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9481                                                 0u,                                                                                             // deUint32                             mipLevel;
9482                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9483                                                 1u,                                                                                             // deUint32                             layerCount;
9484                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9485                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9486                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9487                                 };
9488                         CopyRegion copyRegion;
9489                         copyRegion.bufferImageCopy = bufferImageCopy;
9490
9491                         params.regions.push_back(copyRegion);
9492                 }
9493                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
9494         }
9495
9496         {
9497                 TestParams                              params;
9498                 deUint32                                arrayLayers = 16u;
9499                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9500                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9501                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9502                 params.dst.image.extent                         = defaultHalfExtent;
9503                 params.dst.image.extent.depth           = arrayLayers;
9504                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9505                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9506                 params.allocationKind                           = allocationKind;
9507                 params.extensionUse                                     = extensionUse;
9508
9509                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9510                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9511                 {
9512                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9513                         const VkBufferImageCopy bufferImageCopy =
9514                                 {
9515                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9516                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
9517                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
9518                                         {
9519                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9520                                                 0u,                                                                                             // deUint32                             mipLevel;
9521                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9522                                                 1u,                                                                                             // deUint32                             layerCount;
9523                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9524                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9525                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9526                                 };
9527                         CopyRegion copyRegion;
9528                         copyRegion.bufferImageCopy = bufferImageCopy;
9529
9530                         params.regions.push_back(copyRegion);
9531                 }
9532                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
9533         }
9534 }
9535
9536 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9537 {
9538         tcu::TestContext&                               testCtx                                 = group->getTestContext();
9539
9540         {
9541                 TestParams                      params;
9542                 params.src.buffer.size  = defaultSize;
9543                 params.dst.buffer.size  = defaultSize;
9544                 params.allocationKind   = allocationKind;
9545                 params.extensionUse             = extensionUse;
9546
9547                 const VkBufferCopy      bufferCopy      =
9548                 {
9549                         0u,                             // VkDeviceSize srcOffset;
9550                         0u,                             // VkDeviceSize dstOffset;
9551                         defaultSize,    // VkDeviceSize size;
9552                 };
9553
9554                 CopyRegion      copyRegion;
9555                 copyRegion.bufferCopy   = bufferCopy;
9556                 params.regions.push_back(copyRegion);
9557
9558                 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
9559         }
9560
9561         // Filter is VK_FILTER_NEAREST.
9562         {
9563                 TestParams                      params;
9564                 params.src.buffer.size  = defaultFourthSize;
9565                 params.dst.buffer.size  = defaultFourthSize;
9566                 params.allocationKind   = allocationKind;
9567                 params.extensionUse             = extensionUse;
9568
9569                 const VkBufferCopy      bufferCopy      =
9570                 {
9571                         12u,    // VkDeviceSize srcOffset;
9572                         4u,             // VkDeviceSize dstOffset;
9573                         1u,             // VkDeviceSize size;
9574                 };
9575
9576                 CopyRegion      copyRegion;
9577                 copyRegion.bufferCopy = bufferCopy;
9578                 params.regions.push_back(copyRegion);
9579
9580                 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
9581         }
9582
9583         {
9584                 const deUint32          size            = 16;
9585                 TestParams                      params;
9586                 params.src.buffer.size  = size;
9587                 params.dst.buffer.size  = size * (size + 1);
9588                 params.allocationKind   = allocationKind;
9589                 params.extensionUse             = extensionUse;
9590
9591                 // Copy region with size 1..size
9592                 for (unsigned int i = 1; i <= size; i++)
9593                 {
9594                         const VkBufferCopy      bufferCopy      =
9595                         {
9596                                 0,                      // VkDeviceSize srcOffset;
9597                                 i * size,       // VkDeviceSize dstOffset;
9598                                 i,                      // VkDeviceSize size;
9599                         };
9600
9601                         CopyRegion      copyRegion;
9602                         copyRegion.bufferCopy = bufferCopy;
9603                         params.regions.push_back(copyRegion);
9604                 }
9605
9606                 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
9607         }
9608 }
9609
9610 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
9611 {
9612         tcu::TestContext& testCtx = group->getTestContext();
9613
9614         // Filter is VK_FILTER_NEAREST.
9615         {
9616                 params.filter                                   = VK_FILTER_NEAREST;
9617                 const std::string description   = "Nearest filter";
9618
9619                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9620                 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
9621
9622                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9623                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
9624                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
9625
9626                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9627                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9628                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
9629         }
9630
9631         // Filter is VK_FILTER_LINEAR.
9632         {
9633                 params.filter                                   = VK_FILTER_LINEAR;
9634                 const std::string description   = "Linear filter";
9635
9636                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9637                 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
9638
9639                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9640                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
9641                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
9642
9643                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9644                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9645                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
9646         }
9647
9648         // Filter is VK_FILTER_CUBIC_EXT.
9649         // Cubic filtering can only be used with 2D images.
9650         if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
9651         {
9652                 params.filter                                   = VK_FILTER_CUBIC_EXT;
9653                 const std::string description   = "Cubic filter";
9654
9655                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9656                 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
9657
9658                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9659                 const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
9660                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
9661
9662                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9663                 const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9664                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
9665         }
9666 }
9667
9668 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
9669 {
9670         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9671         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9672         params.src.image.extent                 = defaultExtent;
9673         params.dst.image.extent                 = defaultExtent;
9674         params.src.image.extent.depth   = imageDepth;
9675         params.dst.image.extent.depth   = imageDepth;
9676
9677         {
9678                 const VkImageBlit imageBlit =
9679                 {
9680                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9681                         {
9682                                 { 0, 0, 0 },
9683                                 { defaultSize, defaultSize, imageDepth }
9684                         },                                      // VkOffset3D                           srcOffsets[2];
9685
9686                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9687                         {
9688                                 { 0, 0, 0 },
9689                                 { defaultSize, defaultSize, imageDepth }
9690                         }                                       // VkOffset3D                           dstOffset[2];
9691                 };
9692
9693                 CopyRegion region;
9694                 region.imageBlit = imageBlit;
9695                 params.regions.push_back(region);
9696         }
9697
9698         addBlittingImageSimpleTests(group, params);
9699 }
9700
9701 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
9702 {
9703         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9704         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9705         params.src.image.extent                 = defaultExtent;
9706         params.dst.image.extent                 = defaultExtent;
9707         params.src.image.extent.depth   = imageDepth;
9708         params.dst.image.extent.depth   = imageDepth;
9709
9710         {
9711                 const VkImageBlit imageBlit =
9712                 {
9713                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9714                         {
9715                                 {0, 0, 0},
9716                                 {defaultSize, defaultSize, imageDepth}
9717                         },                                      // VkOffset3D                           srcOffsets[2];
9718
9719                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9720                         {
9721                                 {defaultSize, defaultSize, 0},
9722                                 {0, 0, imageDepth}
9723                         }                                       // VkOffset3D                           dstOffset[2];
9724                 };
9725
9726                 CopyRegion region;
9727                 region.imageBlit = imageBlit;
9728                 params.regions.push_back(region);
9729         }
9730
9731         addBlittingImageSimpleTests(group, params);
9732 }
9733
9734 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
9735 {
9736         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9737         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9738         params.src.image.extent                 = defaultExtent;
9739         params.dst.image.extent                 = defaultExtent;
9740         params.src.image.extent.depth   = imageDepth;
9741         params.dst.image.extent.depth   = imageDepth;
9742
9743         {
9744                 const VkImageBlit imageBlit =
9745                 {
9746                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9747                         {
9748                                 {0, 0, 0},
9749                                 {defaultSize, defaultSize, imageDepth}
9750                         },                                      // VkOffset3D                           srcOffsets[2];
9751
9752                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9753                         {
9754                                 {defaultSize, 0, 0},
9755                                 {0, defaultSize, imageDepth}
9756                         }                                       // VkOffset3D                           dstOffset[2];
9757                 };
9758
9759                 CopyRegion region;
9760                 region.imageBlit = imageBlit;
9761                 params.regions.push_back(region);
9762         }
9763
9764         addBlittingImageSimpleTests(group, params);
9765 }
9766
9767 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
9768 {
9769         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9770         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9771         params.src.image.extent                 = defaultExtent;
9772         params.dst.image.extent                 = defaultExtent;
9773         params.src.image.extent.depth   = imageDepth;
9774         params.dst.image.extent.depth   = imageDepth;
9775
9776         {
9777                 const VkImageBlit imageBlit =
9778                 {
9779                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9780                         {
9781                                 {0, 0, 0},
9782                                 {defaultSize, defaultSize, imageDepth}
9783                         },                                      // VkOffset3D                           srcOffsets[2];
9784
9785                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9786                         {
9787                                 {0, defaultSize, 0},
9788                                 {defaultSize, 0, imageDepth}
9789                         }                                       // VkOffset3D                           dstOffset[2];
9790                 };
9791
9792                 CopyRegion region;
9793                 region.imageBlit = imageBlit;
9794                 params.regions.push_back(region);
9795         }
9796
9797         addBlittingImageSimpleTests(group, params);
9798 }
9799
9800 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
9801 {
9802         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9803         DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
9804         params.src.image.extent                 = defaultExtent;
9805         params.dst.image.extent                 = defaultExtent;
9806         params.src.image.extent.depth   = defaultSize;
9807         params.dst.image.extent.depth   = defaultSize;
9808
9809         {
9810                 const VkImageBlit imageBlit =
9811                 {
9812                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9813                         {
9814                                 {0, 0, 0},
9815                                 {defaultSize, defaultSize, defaultSize}
9816                         },                                      // VkOffset3D                           srcOffsets[2];
9817
9818                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9819                         {
9820                                 {0, 0, defaultSize},
9821                                 {defaultSize, defaultSize, 0}
9822                         }                                       // VkOffset3D                           dstOffset[2];
9823                 };
9824
9825                 CopyRegion region;
9826                 region.imageBlit = imageBlit;
9827                 params.regions.push_back(region);
9828         }
9829
9830         addBlittingImageSimpleTests(group, params);
9831 }
9832
9833 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
9834 {
9835         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9836         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9837         params.src.image.extent                 = defaultExtent;
9838         params.dst.image.extent                 = defaultExtent;
9839         params.src.image.extent.depth   = imageDepth;
9840         params.dst.image.extent.depth   = imageDepth;
9841
9842         // No mirroring.
9843         {
9844                 const VkImageBlit imageBlit =
9845                 {
9846                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9847                         {
9848                                 {0, 0, 0},
9849                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9850                         },                                      // VkOffset3D                           srcOffsets[2];
9851
9852                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9853                         {
9854                                 {0, 0, 0},
9855                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9856                         }                                       // VkOffset3D                           dstOffset[2];
9857                 };
9858
9859                 CopyRegion region;
9860                 region.imageBlit = imageBlit;
9861                 params.regions.push_back(region);
9862         }
9863
9864         // Flipping y coordinates.
9865         {
9866                 const VkImageBlit imageBlit =
9867                 {
9868                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9869                         {
9870                                 {defaultHalfSize, 0, 0},
9871                                 {defaultSize, defaultHalfSize, imageDepth}
9872                         },                                      // VkOffset3D                           srcOffsets[2];
9873
9874                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9875                         {
9876                                 {defaultHalfSize, defaultHalfSize, 0},
9877                                 {defaultSize, 0, imageDepth}
9878                         }                                       // VkOffset3D                           dstOffset[2];
9879                 };
9880                 CopyRegion region;
9881                 region.imageBlit = imageBlit;
9882                 params.regions.push_back(region);
9883         }
9884
9885         // Flipping x coordinates.
9886         {
9887                 const VkImageBlit imageBlit =
9888                 {
9889                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9890                         {
9891                                 {0, defaultHalfSize, 0},
9892                                 {defaultHalfSize, defaultSize, imageDepth}
9893                         },                                      // VkOffset3D                           srcOffsets[2];
9894
9895                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9896                         {
9897                                 {defaultHalfSize, defaultHalfSize, 0},
9898                                 {0, defaultSize, imageDepth}
9899                         }                                       // VkOffset3D                           dstOffset[2];
9900                 };
9901
9902                 CopyRegion region;
9903                 region.imageBlit = imageBlit;
9904                 params.regions.push_back(region);
9905         }
9906
9907         // Flipping x and y coordinates.
9908         {
9909                 const VkImageBlit imageBlit =
9910                 {
9911                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9912                         {
9913                                 {defaultHalfSize, defaultHalfSize, 0},
9914                                 {defaultSize, defaultSize, imageDepth}
9915                         },                                      // VkOffset3D                           srcOffsets[2];
9916
9917                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9918                         {
9919                                 {defaultSize, defaultSize, 0},
9920                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9921                         }                                       // VkOffset3D                           dstOffset[2];
9922                 };
9923
9924                 CopyRegion region;
9925                 region.imageBlit = imageBlit;
9926                 params.regions.push_back(region);
9927         }
9928
9929         addBlittingImageSimpleTests(group, params);
9930 }
9931
9932 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
9933 {
9934         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9935         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9936         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
9937         params.src.image.extent                 = defaultExtent;
9938         params.dst.image.extent                 = defaultHalfExtent;
9939         params.src.image.extent.depth   = imageDepth;
9940         params.dst.image.extent.depth   = halfImageDepth;
9941
9942         {
9943                 const VkImageBlit imageBlit =
9944                 {
9945                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9946                         {
9947                                 {0, 0, 0},
9948                                 {defaultSize, defaultSize, imageDepth}
9949                         },                                      // VkOffset3D                                   srcOffsets[2];
9950
9951                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9952                         {
9953                                 {0, 0, 0},
9954                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
9955                         }                                       // VkOffset3D                                   dstOffset[2];
9956                 };
9957
9958                 CopyRegion region;
9959                 region.imageBlit = imageBlit;
9960                 params.regions.push_back(region);
9961         }
9962
9963         addBlittingImageSimpleTests(group, params);
9964 }
9965
9966 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
9967 {
9968         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9969         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9970         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
9971         params.src.image.extent                 = defaultHalfExtent;
9972         params.dst.image.extent                 = defaultExtent;
9973         params.src.image.extent.depth   = halfImageDepth;
9974         params.dst.image.extent.depth   = imageDepth;
9975
9976         {
9977                 const VkImageBlit imageBlit =
9978                 {
9979                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9980                         {
9981                                 {0, 0, 0},
9982                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
9983                         },                                      // VkOffset3D                                   srcOffsets[2];
9984
9985                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9986                         {
9987                                 {0, 0, 0},
9988                                 {defaultSize, defaultSize, imageDepth}
9989                         }                                       // VkOffset3D                                   dstOffset[2];
9990                 };
9991
9992                 CopyRegion region;
9993                 region.imageBlit = imageBlit;
9994                 params.regions.push_back(region);
9995         }
9996
9997         addBlittingImageSimpleTests(group, params);
9998 }
9999
10000 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
10001 {
10002         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10003         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10004         const deInt32   srcDepthOffset  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
10005         const deInt32   srcDepthSize    = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
10006         params.src.image.extent                 = defaultExtent;
10007         params.dst.image.extent                 = defaultExtent;
10008         params.src.image.extent.depth   = imageDepth;
10009         params.dst.image.extent.depth   = imageDepth;
10010
10011         {
10012                 const VkImageBlit imageBlit =
10013                 {
10014                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10015                         {
10016                                 {defaultFourthSize, defaultFourthSize, srcDepthOffset},
10017                                 {defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
10018                         },                                      // VkOffset3D                                   srcOffsets[2];
10019
10020                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10021                         {
10022                                 {0, 0, 0},
10023                                 {defaultSize, defaultSize, imageDepth}
10024                         }                                       // VkOffset3D                                   dstOffset[2];
10025                 };
10026
10027                 CopyRegion region;
10028                 region.imageBlit = imageBlit;
10029                 params.regions.push_back(region);
10030         }
10031
10032         addBlittingImageSimpleTests(group, params);
10033 }
10034
10035 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
10036 {
10037         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10038         const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
10039         params.src.image.extent = defaultExtent;
10040         params.dst.image.extent = defaultExtent;
10041
10042         if (is3dBlit)
10043         {
10044                 params.src.image.extent.depth = defaultSize;
10045                 params.dst.image.extent.depth = defaultSize;
10046         }
10047
10048         {
10049                 CopyRegion region;
10050                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
10051                 {
10052                         const VkImageBlit imageBlit =
10053                         {
10054                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10055                                 {
10056                                         {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
10057                                         {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
10058                                 },                                      // VkOffset3D                                   srcOffsets[2];
10059
10060                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10061                                 {
10062                                         {i, i, is3dBlit ? i : 0},
10063                                         {i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
10064                                 }                                       // VkOffset3D                                   dstOffset[2];
10065                         };
10066                         region.imageBlit = imageBlit;
10067                         params.regions.push_back(region);
10068                 }
10069         }
10070
10071         addBlittingImageSimpleTests(group, params);
10072 }
10073
10074 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10075 {
10076         TestParams params;
10077         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10078         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10079         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10080         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10081         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10082         params.allocationKind                           = allocationKind;
10083         params.extensionUse                                     = extensionUse;
10084         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10085         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10086         addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10087         addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
10088         addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
10089         addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
10090         addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10091         addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10092         addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10093         addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10094         addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10095
10096         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
10097         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
10098         addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10099         addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
10100         addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
10101         addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
10102         addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
10103         addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10104         addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10105         addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10106         addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10107         addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10108 }
10109
10110 enum FilterMaskBits
10111 {
10112         FILTER_MASK_NEAREST     = 0,                    // Always tested.
10113         FILTER_MASK_LINEAR      = (1u << 0),
10114         FILTER_MASK_CUBIC       = (1u << 1),
10115 };
10116
10117 using FilterMask = deUint32;
10118
10119 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
10120 {
10121         FilterMask mask = FILTER_MASK_NEAREST;
10122
10123         if (!onlyNearest)
10124         {
10125                 mask |= FILTER_MASK_LINEAR;
10126                 if (!discardCubicFilter)
10127                         mask |= FILTER_MASK_CUBIC;
10128         }
10129
10130         return mask;
10131 }
10132
10133 struct BlitColorTestParams
10134 {
10135         TestParams              params;
10136         const VkFormat* compatibleFormats;
10137         FilterMask              testFilters;
10138 };
10139
10140 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
10141 {
10142         bool result = true;
10143
10144         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
10145         {
10146                 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
10147
10148                 result =
10149                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
10150                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
10151         }
10152
10153         return result;
10154 }
10155
10156 const VkFormat  linearOtherImageFormatsToTest[] =
10157 {
10158         // From compatibleFormats8Bit
10159         VK_FORMAT_R4G4_UNORM_PACK8,
10160         VK_FORMAT_R8_SRGB,
10161
10162         // From compatibleFormats16Bit
10163         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10164         VK_FORMAT_R16_SFLOAT,
10165
10166         // From compatibleFormats24Bit
10167         VK_FORMAT_R8G8B8_UNORM,
10168         VK_FORMAT_B8G8R8_SRGB,
10169
10170         // From compatibleFormats32Bit
10171         VK_FORMAT_R8G8B8A8_UNORM,
10172         VK_FORMAT_R32_SFLOAT,
10173
10174         // From compatibleFormats48Bit
10175         VK_FORMAT_R16G16B16_UNORM,
10176         VK_FORMAT_R16G16B16_SFLOAT,
10177
10178         // From compatibleFormats64Bit
10179         VK_FORMAT_R16G16B16A16_UNORM,
10180         VK_FORMAT_R64_SFLOAT,
10181
10182         // From compatibleFormats96Bit
10183         VK_FORMAT_R32G32B32_UINT,
10184         VK_FORMAT_R32G32B32_SFLOAT,
10185
10186         // From compatibleFormats128Bit
10187         VK_FORMAT_R32G32B32A32_UINT,
10188         VK_FORMAT_R64G64_SFLOAT,
10189
10190         // From compatibleFormats192Bit
10191         VK_FORMAT_R64G64B64_UINT,
10192         VK_FORMAT_R64G64B64_SFLOAT,
10193
10194         // From compatibleFormats256Bit
10195         VK_FORMAT_R64G64B64A64_UINT,
10196         VK_FORMAT_R64G64B64A64_SFLOAT,
10197 };
10198
10199 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
10200 {
10201         switch (tiling)
10202         {
10203                 case VK_IMAGE_TILING_OPTIMAL:
10204                         return getImageLayoutCaseName(layout);
10205                 case VK_IMAGE_TILING_LINEAR:
10206                         return "linear";
10207                 default:
10208                         DE_ASSERT(false);
10209                         return "";
10210         }
10211 }
10212
10213 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10214 {
10215         tcu::TestContext& testCtx                               = group->getTestContext();
10216
10217         FormatSet linearOtherImageFormatsToTestSet;
10218         const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
10219         for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
10220                 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
10221
10222         const VkImageTiling blitSrcTilings[]    =
10223         {
10224                 VK_IMAGE_TILING_OPTIMAL,
10225                 VK_IMAGE_TILING_LINEAR,
10226         };
10227         const VkImageLayout blitSrcLayouts[]    =
10228         {
10229                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10230                 VK_IMAGE_LAYOUT_GENERAL
10231         };
10232         const VkImageTiling blitDstTilings[]    =
10233         {
10234                 VK_IMAGE_TILING_OPTIMAL,
10235                 VK_IMAGE_TILING_LINEAR,
10236         };
10237         const VkImageLayout blitDstLayouts[]    =
10238         {
10239                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10240                 VK_IMAGE_LAYOUT_GENERAL
10241         };
10242
10243         for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
10244         {
10245                 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
10246
10247                 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10248                 {
10249                         testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
10250
10251                         // 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
10252                         if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
10253                                 continue;
10254
10255                         for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
10256                         {
10257                                 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
10258
10259                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10260                                 {
10261                                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
10262
10263                                         // 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
10264                                         if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
10265                                                 continue;
10266
10267                                         if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
10268                                             (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
10269                                                 continue;
10270
10271                                         testParams.params.filter                        = VK_FILTER_NEAREST;
10272                                         const std::string testName                      = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
10273                                                                                                                   getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10274                                         const std::string description           = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
10275                                                                                                                   " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10276                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
10277
10278                                         if (testParams.testFilters & FILTER_MASK_LINEAR)
10279                                         {
10280                                                 testParams.params.filter = VK_FILTER_LINEAR;
10281                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
10282                                         }
10283
10284                                         if (testParams.testFilters & FILTER_MASK_CUBIC)
10285                                         {
10286                                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
10287                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
10288                                         }
10289
10290                                         if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
10291                                         {
10292                                                 const struct
10293                                                 {
10294                                                         FillMode        mode;
10295                                                         const char*     name;
10296                                                 } modeList[] =
10297                                                 {
10298                                                         { FILL_MODE_BLUE_RED_X, "x" },
10299                                                         { FILL_MODE_BLUE_RED_Y, "y" },
10300                                                         { FILL_MODE_BLUE_RED_Z, "z" },
10301                                                 };
10302
10303                                                 auto otherParams = testParams;
10304                                                 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
10305
10306                                                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
10307                                                 {
10308                                                         otherParams.params.src.image.fillMode = modeList[i].mode;
10309
10310                                                         otherParams.params.filter = VK_FILTER_LINEAR;
10311                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
10312
10313                                                         otherParams.params.filter = VK_FILTER_NEAREST;
10314                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
10315                                                 }
10316                                         }
10317                                 }
10318                         }
10319                 }
10320         }
10321 }
10322
10323 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10324 {
10325         VkFormat srcFormat = testParams.params.src.image.format;
10326
10327         if (testParams.compatibleFormats)
10328         {
10329                 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
10330                 {
10331                         testParams.params.dst.image.format      = testParams.compatibleFormats[dstFormatIndex];
10332                         if (!isSupportedByFramework(testParams.params.dst.image.format))
10333                                 continue;
10334
10335                         if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
10336                                 continue;
10337
10338                         const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
10339                         addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10340                 }
10341         }
10342
10343         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
10344         // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
10345         // as it is not on compatibleFormats list
10346         if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
10347         {
10348                 testParams.params.dst.image.format = srcFormat;
10349
10350                 const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
10351                 addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10352         }
10353 }
10354
10355 const VkFormat  compatibleFormatsUInts[]        =
10356 {
10357         VK_FORMAT_R8_UINT,
10358         VK_FORMAT_R8G8_UINT,
10359         VK_FORMAT_R8G8B8_UINT,
10360         VK_FORMAT_B8G8R8_UINT,
10361         VK_FORMAT_R8G8B8A8_UINT,
10362         VK_FORMAT_B8G8R8A8_UINT,
10363         VK_FORMAT_A8B8G8R8_UINT_PACK32,
10364         VK_FORMAT_A2R10G10B10_UINT_PACK32,
10365         VK_FORMAT_A2B10G10R10_UINT_PACK32,
10366         VK_FORMAT_R16_UINT,
10367         VK_FORMAT_R16G16_UINT,
10368         VK_FORMAT_R16G16B16_UINT,
10369         VK_FORMAT_R16G16B16A16_UINT,
10370         VK_FORMAT_R32_UINT,
10371         VK_FORMAT_R32G32_UINT,
10372         VK_FORMAT_R32G32B32_UINT,
10373         VK_FORMAT_R32G32B32A32_UINT,
10374         VK_FORMAT_R64_UINT,
10375         VK_FORMAT_R64G64_UINT,
10376         VK_FORMAT_R64G64B64_UINT,
10377         VK_FORMAT_R64G64B64A64_UINT,
10378
10379         VK_FORMAT_UNDEFINED
10380 };
10381 const VkFormat  compatibleFormatsSInts[]        =
10382 {
10383         VK_FORMAT_R8_SINT,
10384         VK_FORMAT_R8G8_SINT,
10385         VK_FORMAT_R8G8B8_SINT,
10386         VK_FORMAT_B8G8R8_SINT,
10387         VK_FORMAT_R8G8B8A8_SINT,
10388         VK_FORMAT_B8G8R8A8_SINT,
10389         VK_FORMAT_A8B8G8R8_SINT_PACK32,
10390         VK_FORMAT_A2R10G10B10_SINT_PACK32,
10391         VK_FORMAT_A2B10G10R10_SINT_PACK32,
10392         VK_FORMAT_R16_SINT,
10393         VK_FORMAT_R16G16_SINT,
10394         VK_FORMAT_R16G16B16_SINT,
10395         VK_FORMAT_R16G16B16A16_SINT,
10396         VK_FORMAT_R32_SINT,
10397         VK_FORMAT_R32G32_SINT,
10398         VK_FORMAT_R32G32B32_SINT,
10399         VK_FORMAT_R32G32B32A32_SINT,
10400         VK_FORMAT_R64_SINT,
10401         VK_FORMAT_R64G64_SINT,
10402         VK_FORMAT_R64G64B64_SINT,
10403         VK_FORMAT_R64G64B64A64_SINT,
10404
10405         VK_FORMAT_UNDEFINED
10406 };
10407 const VkFormat  compatibleFormatsFloats[]       =
10408 {
10409         VK_FORMAT_R4G4_UNORM_PACK8,
10410         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10411         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
10412         VK_FORMAT_R5G6B5_UNORM_PACK16,
10413         VK_FORMAT_B5G6R5_UNORM_PACK16,
10414         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
10415         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
10416         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
10417         VK_FORMAT_R8_UNORM,
10418         VK_FORMAT_R8_SNORM,
10419         VK_FORMAT_R8_USCALED,
10420         VK_FORMAT_R8_SSCALED,
10421         VK_FORMAT_R8G8_UNORM,
10422         VK_FORMAT_R8G8_SNORM,
10423         VK_FORMAT_R8G8_USCALED,
10424         VK_FORMAT_R8G8_SSCALED,
10425         VK_FORMAT_R8G8B8_UNORM,
10426         VK_FORMAT_R8G8B8_SNORM,
10427         VK_FORMAT_R8G8B8_USCALED,
10428         VK_FORMAT_R8G8B8_SSCALED,
10429         VK_FORMAT_B8G8R8_UNORM,
10430         VK_FORMAT_B8G8R8_SNORM,
10431         VK_FORMAT_B8G8R8_USCALED,
10432         VK_FORMAT_B8G8R8_SSCALED,
10433         VK_FORMAT_R8G8B8A8_UNORM,
10434         VK_FORMAT_R8G8B8A8_SNORM,
10435         VK_FORMAT_R8G8B8A8_USCALED,
10436         VK_FORMAT_R8G8B8A8_SSCALED,
10437         VK_FORMAT_B8G8R8A8_UNORM,
10438         VK_FORMAT_B8G8R8A8_SNORM,
10439         VK_FORMAT_B8G8R8A8_USCALED,
10440         VK_FORMAT_B8G8R8A8_SSCALED,
10441         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
10442         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
10443         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10444         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10445         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
10446         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
10447         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
10448         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
10449         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
10450         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
10451         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
10452         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
10453         VK_FORMAT_R16_UNORM,
10454         VK_FORMAT_R16_SNORM,
10455         VK_FORMAT_R16_USCALED,
10456         VK_FORMAT_R16_SSCALED,
10457         VK_FORMAT_R16_SFLOAT,
10458         VK_FORMAT_R16G16_UNORM,
10459         VK_FORMAT_R16G16_SNORM,
10460         VK_FORMAT_R16G16_USCALED,
10461         VK_FORMAT_R16G16_SSCALED,
10462         VK_FORMAT_R16G16_SFLOAT,
10463         VK_FORMAT_R16G16B16_UNORM,
10464         VK_FORMAT_R16G16B16_SNORM,
10465         VK_FORMAT_R16G16B16_USCALED,
10466         VK_FORMAT_R16G16B16_SSCALED,
10467         VK_FORMAT_R16G16B16_SFLOAT,
10468         VK_FORMAT_R16G16B16A16_UNORM,
10469         VK_FORMAT_R16G16B16A16_SNORM,
10470         VK_FORMAT_R16G16B16A16_USCALED,
10471         VK_FORMAT_R16G16B16A16_SSCALED,
10472         VK_FORMAT_R16G16B16A16_SFLOAT,
10473         VK_FORMAT_R32_SFLOAT,
10474         VK_FORMAT_R32G32_SFLOAT,
10475         VK_FORMAT_R32G32B32_SFLOAT,
10476         VK_FORMAT_R32G32B32A32_SFLOAT,
10477         VK_FORMAT_R64_SFLOAT,
10478         VK_FORMAT_R64G64_SFLOAT,
10479         VK_FORMAT_R64G64B64_SFLOAT,
10480         VK_FORMAT_R64G64B64A64_SFLOAT,
10481         VK_FORMAT_B10G11R11_UFLOAT_PACK32,
10482         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10483
10484         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
10485         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
10486
10487         VK_FORMAT_UNDEFINED
10488 };
10489
10490 const VkFormat  compressedFormatsFloats[] =
10491 {
10492         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
10493         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
10494         VK_FORMAT_BC2_UNORM_BLOCK,
10495         VK_FORMAT_BC3_UNORM_BLOCK,
10496         VK_FORMAT_BC4_UNORM_BLOCK,
10497         VK_FORMAT_BC4_SNORM_BLOCK,
10498         VK_FORMAT_BC5_UNORM_BLOCK,
10499         VK_FORMAT_BC5_SNORM_BLOCK,
10500         VK_FORMAT_BC6H_UFLOAT_BLOCK,
10501         VK_FORMAT_BC6H_SFLOAT_BLOCK,
10502         VK_FORMAT_BC7_UNORM_BLOCK,
10503         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
10504         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
10505         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
10506         VK_FORMAT_EAC_R11_UNORM_BLOCK,
10507         VK_FORMAT_EAC_R11_SNORM_BLOCK,
10508         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
10509         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
10510
10511         VK_FORMAT_UNDEFINED
10512 };
10513
10514 const VkFormat  compatibleFormatsSrgb[]         =
10515 {
10516         VK_FORMAT_R8_SRGB,
10517         VK_FORMAT_R8G8_SRGB,
10518         VK_FORMAT_R8G8B8_SRGB,
10519         VK_FORMAT_B8G8R8_SRGB,
10520         VK_FORMAT_R8G8B8A8_SRGB,
10521         VK_FORMAT_B8G8R8A8_SRGB,
10522         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10523
10524         VK_FORMAT_UNDEFINED
10525 };
10526
10527 const VkFormat  compressedFormatsSrgb[] =
10528 {
10529         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
10530         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
10531         VK_FORMAT_BC2_SRGB_BLOCK,
10532         VK_FORMAT_BC3_SRGB_BLOCK,
10533         VK_FORMAT_BC7_SRGB_BLOCK,
10534         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
10535         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
10536         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
10537
10538         VK_FORMAT_UNDEFINED
10539 };
10540
10541 const VkFormat  dedicatedAllocationBlittingFormatsToTest[]      =
10542 {
10543         // compatibleFormatsUInts
10544         VK_FORMAT_R8_UINT,
10545         VK_FORMAT_R64G64B64A64_UINT,
10546
10547         // compatibleFormatsSInts
10548         VK_FORMAT_R8_SINT,
10549         VK_FORMAT_R64G64B64A64_SINT,
10550
10551         // compatibleFormatsFloats
10552         VK_FORMAT_R4G4_UNORM_PACK8,
10553         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10554
10555         // compatibleFormatsSrgb
10556         VK_FORMAT_R8_SRGB,
10557         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10558 };
10559
10560 // skip cubic filtering test for the following data formats
10561 const FormatSet onlyNearestAndLinearFormatsToTest =
10562 {
10563         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10564         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10565         VK_FORMAT_A8B8G8R8_UINT_PACK32,
10566         VK_FORMAT_A8B8G8R8_SINT_PACK32
10567 };
10568
10569 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight)
10570 {
10571         CopyRegion                              region;
10572         std::vector<CopyRegion> regionsVector;
10573         deInt32                                 fourthOfSrcWidth        = srcWidth / 4;
10574         deInt32                                 fourthOfSrcHeight       = srcHeight / 4;
10575
10576         // to the top of resulting image copy whole source image but with increasingly smaller sizes
10577         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
10578         {
10579                 region.imageBlit =
10580                 {
10581                         defaultSourceLayer,                                             // VkImageSubresourceLayers             srcSubresource;
10582                         {
10583                                 {0, 0, 0},
10584                                 {srcWidth, srcHeight, 1}
10585                         },                                                                              // VkOffset3D                                   srcOffsets[2];
10586
10587                         defaultSourceLayer,                                             // VkImageSubresourceLayers             dstSubresource;
10588                         {
10589                                 {i, 0, 0},
10590                                 {i + defaultFourthSize / j, defaultFourthSize / j, 1}
10591                         }                                                                               // VkOffset3D                                   dstOffset[2];
10592                 };
10593                 regionsVector.push_back(region);
10594         }
10595
10596         // to the bottom of resulting image copy parts of source image
10597         int srcX = 0;
10598         int srcY = 0;
10599         for (int i = 0; i < defaultSize; i += defaultFourthSize)
10600         {
10601                 region.imageBlit =
10602                 {
10603                         defaultSourceLayer,                                             // VkImageSubresourceLayers             srcSubresource;
10604                         {
10605                                 {srcX, srcY, 0},
10606                                 {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
10607                         },                                                                              // VkOffset3D                                   srcOffsets[2];
10608
10609                         defaultSourceLayer,                                             // VkImageSubresourceLayers             dstSubresource;
10610                         {
10611                                 {i, defaultSize / 2, 0},
10612                                 {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
10613                         }                                                                               // VkOffset3D                                   dstOffset[2];
10614                 };
10615                 regionsVector.push_back(region);
10616                 srcX += fourthOfSrcWidth;
10617                 srcY += fourthOfSrcHeight;
10618         }
10619
10620         return regionsVector;
10621 }
10622
10623 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10624 {
10625         const struct {
10626                 const VkFormat* sourceFormats;
10627                 const VkFormat* destinationFormats;
10628                 const bool              onlyNearest;
10629         }       colorImageFormatsToTestBlit[] =
10630         {
10631                 { compatibleFormatsUInts,       compatibleFormatsUInts,         true    },
10632                 { compatibleFormatsSInts,       compatibleFormatsSInts,         true    },
10633                 { compatibleFormatsFloats,      compatibleFormatsFloats,        false   },
10634                 { compressedFormatsFloats,      compatibleFormatsFloats,        false   },
10635                 { compatibleFormatsSrgb,        compatibleFormatsSrgb,          false   },
10636                 { compressedFormatsSrgb,        compatibleFormatsSrgb,          false   },
10637         };
10638
10639         const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
10640
10641         if (allocationKind == ALLOCATION_KIND_DEDICATED)
10642         {
10643                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
10644                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
10645                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
10646         }
10647
10648         // 2D tests.
10649         {
10650                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
10651
10652                 TestParams      params;
10653                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
10654                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
10655                 params.src.image.extent         = defaultExtent;
10656                 params.dst.image.extent         = defaultExtent;
10657                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10658                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10659                 params.allocationKind           = allocationKind;
10660                 params.extensionUse                     = extensionUse;
10661
10662                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10663                 {
10664                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10665                         const VkFormat* destinationFormats      = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
10666                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10667                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10668                         {
10669                                 VkFormat srcFormat              = sourceFormats[srcFormatIndex];
10670                                 params.src.image.format = srcFormat;
10671
10672                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
10673
10674                                 params.regions                  = create2DCopyRegions(64, 64);
10675
10676                                 const VkOffset3D&       srcImageSize    = params.regions[0].imageBlit.srcOffsets[1];
10677                                 VkExtent3D&                     srcImageExtent  = params.src.image.extent;
10678                                 srcImageExtent.width    = srcImageSize.x;
10679                                 srcImageExtent.height   = srcImageSize.y;
10680
10681                                 BlitColorTestParams testParams
10682                                 {
10683                                         params,
10684                                         destinationFormats,
10685                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10686                                 };
10687
10688                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10689                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10690                         }
10691                 }
10692
10693                 group->addChild(subGroup.release());
10694         }
10695
10696         // 1D tests.
10697         {
10698                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
10699
10700                 TestParams      params;
10701                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
10702                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
10703                 params.src.image.extent         = default1dExtent;
10704                 params.dst.image.extent         = default1dExtent;
10705                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10706                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10707                 params.allocationKind           = allocationKind;
10708                 params.extensionUse                     = extensionUse;
10709
10710                 CopyRegion      region;
10711                 for (int i = 0; i < defaultSize; i += defaultSize / 2)
10712                 {
10713                         const VkImageBlit                       imageBlit       =
10714                         {
10715                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10716                                 {
10717                                         {0, 0, 0},
10718                                         {defaultSize, 1, 1}
10719                                 },                                      // VkOffset3D                                   srcOffsets[2];
10720
10721                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10722                                 {
10723                                         {i, 0, 0},
10724                                         {i + defaultFourthSize, 1, 1}
10725                                 }                                       // VkOffset3D                                   dstOffset[2];
10726                         };
10727                         region.imageBlit        = imageBlit;
10728                         params.regions.push_back(region);
10729                 }
10730
10731                 {
10732                         const VkImageBlit                       imageBlit       =
10733                         {
10734                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10735                                 {
10736                                         {0, 0, 0},
10737                                         {defaultFourthSize, 1, 1}
10738                                 },                                      // VkOffset3D                                   srcOffsets[2];
10739
10740                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10741                                 {
10742                                         {defaultFourthSize, 0, 0},
10743                                         {2 * defaultFourthSize, 1, 1}
10744                                 }                                       // VkOffset3D                                   dstOffset[2];
10745                         };
10746                         region.imageBlit        = imageBlit;
10747                         params.regions.push_back(region);
10748                 }
10749
10750                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10751                 {
10752                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10753                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10754                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10755                         {
10756                                 params.src.image.format = sourceFormats[srcFormatIndex];
10757                                 if (!isSupportedByFramework(params.src.image.format))
10758                                         continue;
10759
10760                                 // Cubic filtering can only be used with 2D images.
10761                                 const bool onlyNearestAndLinear = true;
10762
10763                                 BlitColorTestParams testParams
10764                                 {
10765                                         params,
10766                                         nullptr,
10767                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10768                                 };
10769
10770                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10771                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10772                         }
10773                 }
10774
10775                 group->addChild(subGroup.release());
10776         }
10777
10778         // 3D tests. Note we use smaller dimensions here for performance reasons.
10779         {
10780                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
10781
10782                 TestParams      params;
10783                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
10784                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
10785                 params.src.image.extent         = default3dExtent;
10786                 params.dst.image.extent         = default3dExtent;
10787                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10788                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10789                 params.allocationKind           = allocationKind;
10790                 params.extensionUse                     = extensionUse;
10791
10792                 CopyRegion      region;
10793                 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
10794                 {
10795                         const VkImageBlit                       imageBlit       =
10796                         {
10797                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10798                                 {
10799                                         {0, 0, 0},
10800                                         {defaultFourthSize, defaultFourthSize, defaultFourthSize}
10801                                 },                                      // VkOffset3D                                   srcOffsets[2];
10802
10803                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10804                                 {
10805                                         {i, 0, i},
10806                                         {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
10807                                 }                                       // VkOffset3D                                   dstOffset[2];
10808                         };
10809                         region.imageBlit        = imageBlit;
10810                         params.regions.push_back(region);
10811                 }
10812                 for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
10813                 {
10814                         const VkImageBlit                       imageBlit       =
10815                         {
10816                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10817                                 {
10818                                         {i, i, i},
10819                                         {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
10820                                 },                                      // VkOffset3D                                   srcOffsets[2];
10821
10822                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10823                                 {
10824                                         {i, defaultFourthSize / 2, i},
10825                                         {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
10826                                 }                                       // VkOffset3D                                   dstOffset[2];
10827                         };
10828                         region.imageBlit        = imageBlit;
10829                         params.regions.push_back(region);
10830                 }
10831
10832                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10833                 {
10834                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10835                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10836                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10837                         {
10838                                 params.src.image.format = sourceFormats[srcFormatIndex];
10839                                 if (!isSupportedByFramework(params.src.image.format))
10840                                         continue;
10841
10842                                 // Cubic filtering can only be used with 2D images.
10843                                 const bool onlyNearestAndLinear = true;
10844
10845                                 BlitColorTestParams testParams
10846                                 {
10847                                         params,
10848                                         nullptr,
10849                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10850                                 };
10851
10852                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10853                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10854                         }
10855                 }
10856
10857                 group->addChild(subGroup.release());
10858         }
10859 }
10860
10861 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
10862 {
10863         const VkImageLayout blitSrcLayouts[]    =
10864         {
10865                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10866                 VK_IMAGE_LAYOUT_GENERAL
10867         };
10868         const VkImageLayout blitDstLayouts[]    =
10869         {
10870                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10871                 VK_IMAGE_LAYOUT_GENERAL
10872         };
10873
10874         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10875         {
10876                 params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
10877
10878                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10879                 {
10880                         params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
10881                         params.filter                                           = VK_FILTER_NEAREST;
10882
10883                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
10884                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
10885                         const std::string description   = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
10886                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
10887
10888                         group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
10889                 }
10890         }
10891 }
10892
10893 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10894 {
10895         const VkFormat  depthAndStencilFormats[]        =
10896         {
10897                 VK_FORMAT_D16_UNORM,
10898                 VK_FORMAT_X8_D24_UNORM_PACK32,
10899                 VK_FORMAT_D32_SFLOAT,
10900                 VK_FORMAT_S8_UINT,
10901                 VK_FORMAT_D16_UNORM_S8_UINT,
10902                 VK_FORMAT_D24_UNORM_S8_UINT,
10903                 VK_FORMAT_D32_SFLOAT_S8_UINT,
10904         };
10905
10906         const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
10907         const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
10908         const VkImageSubresourceLayers  defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
10909
10910         // 2D tests
10911         {
10912                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
10913
10914                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
10915                 {
10916                         TestParams      params;
10917                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10918                         params.src.image.extent                         = defaultExtent;
10919                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10920                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
10921                         params.dst.image.extent                         = defaultExtent;
10922                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10923                         params.dst.image.format                         = params.src.image.format;
10924                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10925                         params.allocationKind                           = allocationKind;
10926                         params.extensionUse                                     = extensionUse;
10927                         params.separateDepthStencilLayouts      = DE_FALSE;
10928
10929                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10930                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10931
10932                         CopyRegion      region;
10933                         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
10934                         {
10935                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
10936                                 const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
10937                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
10938                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
10939
10940                                 if (hasDepth)
10941                                 {
10942                                         const VkImageBlit                       imageBlit       =
10943                                         {
10944                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
10945                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
10946                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
10947                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
10948                                         };
10949                                         region.imageBlit        = imageBlit;
10950                                         params.regions.push_back(region);
10951                                 }
10952                                 if (hasStencil)
10953                                 {
10954                                         const VkImageBlit                       imageBlit       =
10955                                         {
10956                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
10957                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
10958                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
10959                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
10960                                         };
10961                                         region.imageBlit        = imageBlit;
10962                                         params.regions.push_back(region);
10963                                 }
10964                         }
10965                         for (int i = 0; i < defaultSize; i += defaultFourthSize)
10966                         {
10967                                 const VkOffset3D        srcOffset0      = {i, i, 0};
10968                                 const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
10969                                 const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
10970                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
10971
10972                                 if (hasDepth)
10973                                 {
10974                                         const VkImageBlit                       imageBlit       =
10975                                         {
10976                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
10977                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
10978                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
10979                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
10980                                         };
10981                                         region.imageBlit        = imageBlit;
10982                                         params.regions.push_back(region);
10983                                 }
10984                                 if (hasStencil)
10985                                 {
10986                                         const VkImageBlit                       imageBlit       =
10987                                         {
10988                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
10989                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
10990                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
10991                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
10992                                         };
10993                                         region.imageBlit        = imageBlit;
10994                                         params.regions.push_back(region);
10995                                 }
10996                                 if (hasDepth && hasStencil)
10997                                 {
10998                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultFourthSize, 0};
10999                                         const VkOffset3D                        dstDSOffset1    = {i + defaultFourthSize, defaultSize, 1};
11000                                         const VkImageBlit                       imageBlit       =
11001                                         {
11002                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
11003                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11004                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
11005                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
11006                                         };
11007                                         region.imageBlit        = imageBlit;
11008                                         params.regions.push_back(region);
11009                                 }
11010                         }
11011
11012                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11013                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11014                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11015                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11016
11017                         if (hasDepth && hasStencil)
11018                         {
11019                                 params.separateDepthStencilLayouts      = DE_TRUE;
11020                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11021                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11022                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11023                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11024                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11025                         }
11026                 }
11027
11028                 group->addChild(subGroup.release());
11029         }
11030
11031         // 1D tests
11032         {
11033                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11034
11035                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11036                 {
11037                         TestParams      params;
11038                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
11039                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
11040                         params.src.image.extent                         = default1dExtent;
11041                         params.dst.image.extent                         = default1dExtent;
11042                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
11043                         params.dst.image.format                         = params.src.image.format;
11044                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11045                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11046                         params.allocationKind                           = allocationKind;
11047                         params.extensionUse                                     = extensionUse;
11048
11049                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11050                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11051
11052                         CopyRegion      region;
11053                         for (int i = 0; i < defaultSize; i += defaultSize / 2)
11054                         {
11055                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11056                                 const VkOffset3D        srcOffset1      = {defaultSize, 1, 1};
11057                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
11058                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, 1, 1};
11059
11060                                 if (hasDepth)
11061                                 {
11062                                         const VkImageBlit                       imageBlit       =
11063                                         {
11064                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11065                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11066                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11067                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11068                                         };
11069                                         region.imageBlit        = imageBlit;
11070                                         params.regions.push_back(region);
11071                                 }
11072                                 if (hasStencil)
11073                                 {
11074                                         const VkImageBlit                       imageBlit       =
11075                                         {
11076                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11077                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11078                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11079                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11080                                         };
11081                                         region.imageBlit        = imageBlit;
11082                                         params.regions.push_back(region);
11083                                 }
11084                         }
11085
11086                         {
11087                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11088                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, 1, 1};
11089                                 const VkOffset3D        dstOffset0      = {defaultFourthSize, 0, 0};
11090                                 const VkOffset3D        dstOffset1      = {2 * defaultFourthSize, 1, 1};
11091
11092                                 if (hasDepth)
11093                                 {
11094                                         const VkImageBlit                       imageBlit       =
11095                                         {
11096                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11097                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11098                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11099                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11100                                         };
11101                                         region.imageBlit        = imageBlit;
11102                                         params.regions.push_back(region);
11103                                 }
11104                                 if (hasStencil)
11105                                 {
11106                                         const VkImageBlit                       imageBlit       =
11107                                         {
11108                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11109                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11110                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11111                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11112                                         };
11113                                         region.imageBlit        = imageBlit;
11114                                         params.regions.push_back(region);
11115                                 }
11116                                 if (hasDepth && hasStencil)
11117                                 {
11118                                         const VkOffset3D                        dstDSOffset0    = {3 * defaultFourthSize, 0, 0};
11119                                         const VkOffset3D                        dstDSOffset1    = {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
11120                                         const VkImageBlit                       imageBlit       =
11121                                         {
11122                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
11123                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11124                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
11125                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
11126                                         };
11127                                         region.imageBlit        = imageBlit;
11128                                         params.regions.push_back(region);
11129                                 }
11130                         }
11131
11132                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11133                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11134                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11135                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11136
11137                         if (hasDepth && hasStencil)
11138                         {
11139                                 params.separateDepthStencilLayouts      = DE_TRUE;
11140                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11141                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11142                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11143                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11144                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11145                         }
11146                 }
11147
11148                 group->addChild(subGroup.release());
11149         }
11150
11151         // 3D tests. Note we use smaller dimensions here for performance reasons.
11152         {
11153                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11154
11155                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11156                 {
11157                         TestParams      params;
11158                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
11159                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
11160                         params.src.image.extent                         = default3dExtent;
11161                         params.dst.image.extent                         = default3dExtent;
11162                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
11163                         params.dst.image.format                         = params.src.image.format;
11164                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11165                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11166                         params.allocationKind                           = allocationKind;
11167                         params.extensionUse                                     = extensionUse;
11168
11169                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11170                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11171
11172                         CopyRegion      region;
11173                         for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11174                         {
11175                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11176                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
11177                                 const VkOffset3D        dstOffset0      = {i, 0, i};
11178                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
11179
11180                                 if (hasDepth)
11181                                 {
11182                                         const VkImageBlit                       imageBlit       =
11183                                         {
11184                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11185                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11186                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11187                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11188                                         };
11189                                         region.imageBlit        = imageBlit;
11190                                         params.regions.push_back(region);
11191                                 }
11192                                 if (hasStencil)
11193                                 {
11194                                         const VkImageBlit                       imageBlit       =
11195                                         {
11196                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11197                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11198                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11199                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11200                                         };
11201                                         region.imageBlit        = imageBlit;
11202                                         params.regions.push_back(region);
11203                                 }
11204                         }
11205                         for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11206                         {
11207                                 const VkOffset3D        srcOffset0      = {i, i, i};
11208                                 const VkOffset3D        srcOffset1      = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
11209                                 const VkOffset3D        dstOffset0      = {i, defaultFourthSize / 2, i};
11210                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
11211
11212                                 if (hasDepth)
11213                                 {
11214                                         const VkImageBlit                       imageBlit       =
11215                                         {
11216                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11217                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11218                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11219                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11220                                         };
11221                                         region.imageBlit        = imageBlit;
11222                                         params.regions.push_back(region);
11223                                 }
11224                                 if (hasStencil)
11225                                 {
11226                                         const VkImageBlit                       imageBlit       =
11227                                         {
11228                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11229                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11230                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11231                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11232                                         };
11233                                         region.imageBlit        = imageBlit;
11234                                         params.regions.push_back(region);
11235                                 }
11236                                 if (hasDepth && hasStencil)
11237                                 {
11238                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultSixteenthSize, i};
11239                                         const VkOffset3D                        dstDSOffset1    = {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
11240                                         const VkImageBlit                       imageBlit       =
11241                                         {
11242                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
11243                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11244                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
11245                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
11246                                         };
11247                                         region.imageBlit        = imageBlit;
11248                                         params.regions.push_back(region);
11249                                 }
11250                         }
11251
11252                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11253                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11254                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11255                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11256
11257                         if (hasDepth && hasStencil)
11258                         {
11259                                 params.separateDepthStencilLayouts      = DE_TRUE;
11260                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11261                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11262                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11263                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11264                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11265                         }
11266                 }
11267
11268                 group->addChild(subGroup.release());
11269         }
11270 }
11271
11272 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
11273 {
11274         tcu::TestContext& testCtx                               = group->getTestContext();
11275
11276         const VkImageLayout blitSrcLayouts[]    =
11277         {
11278                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11279                 VK_IMAGE_LAYOUT_GENERAL
11280         };
11281         const VkImageLayout blitDstLayouts[]    =
11282         {
11283                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11284                 VK_IMAGE_LAYOUT_GENERAL
11285         };
11286
11287         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11288         {
11289                 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
11290                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11291                 {
11292                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
11293
11294                         testParams.params.filter                        = VK_FILTER_NEAREST;
11295                         const std::string testName                      = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
11296                                                                                                   getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11297                         const std::string description           = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
11298                                                                                                   " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11299                         group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
11300
11301                         if (testParams.testFilters & FILTER_MASK_LINEAR)
11302                         {
11303                                 testParams.params.filter = VK_FILTER_LINEAR;
11304                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
11305                         }
11306
11307                         if (testParams.testFilters & FILTER_MASK_CUBIC)
11308                         {
11309                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
11310                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
11311                         }
11312                 }
11313         }
11314 }
11315
11316 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11317 {
11318         const struct
11319         {
11320                 const VkFormat* const   compatibleFormats;
11321                 const bool                              onlyNearest;
11322         }       colorImageFormatsToTestBlit[]                   =
11323         {
11324                 { compatibleFormatsUInts,       true    },
11325                 { compatibleFormatsSInts,       true    },
11326                 { compatibleFormatsFloats,      false   },
11327                 { compatibleFormatsSrgb,        false   },
11328         };
11329
11330         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11331
11332         const int       layerCountsToTest[]                             =
11333         {
11334                 1,
11335                 6
11336         };
11337
11338         TestParams      params;
11339         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
11340         params.src.image.extent         = defaultExtent;
11341         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11342         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
11343         params.dst.image.extent         = defaultExtent;
11344         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11345         params.allocationKind           = allocationKind;
11346         params.extensionUse                     = extensionUse;
11347         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11348         params.singleCommand            = DE_TRUE;
11349
11350         CopyRegion      region;
11351         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11352         {
11353                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
11354                 destLayer.mipLevel = mipLevelNdx;
11355
11356                 const VkImageBlit                       imageBlit       =
11357                 {
11358                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
11359                         {
11360                                 {0, 0, 0},
11361                                 {defaultSize, defaultSize, 1}
11362                         },                                      // VkOffset3D                                   srcOffsets[2];
11363
11364                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
11365                         {
11366                                 {0, 0, 0},
11367                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11368                         }                                       // VkOffset3D                                   dstOffset[2];
11369                 };
11370                 region.imageBlit        = imageBlit;
11371                 params.regions.push_back(region);
11372         }
11373
11374         if (allocationKind == ALLOCATION_KIND_DEDICATED)
11375         {
11376                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11377                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11378                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11379         }
11380
11381         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11382         {
11383                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
11384                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
11385                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11386
11387                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11388
11389                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11390                 {
11391                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11392                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11393
11394                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11395                         {
11396                                 params.src.image.format = compatibleFormats[srcFormatIndex];
11397                                 params.dst.image.format = compatibleFormats[srcFormatIndex];
11398
11399                                 if (!isSupportedByFramework(params.src.image.format))
11400                                         continue;
11401
11402                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11403
11404                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
11405
11406                                 BlitColorTestParams testParams;
11407                                 testParams.params                               = params;
11408                                 testParams.compatibleFormats    = compatibleFormats;
11409                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
11410
11411                                 testParams.params.src.image.extent.depth = layerCount;
11412                                 testParams.params.dst.image.extent.depth = layerCount;
11413
11414                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11415                                 {
11416                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11417                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11418                                 }
11419
11420                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11421                         }
11422                 }
11423                 group->addChild(layerCountGroup.release());
11424         }
11425 }
11426
11427 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11428 {
11429         const struct
11430         {
11431                 const VkFormat* const   compatibleFormats;
11432                 const bool                              onlyNearest;
11433         }       colorImageFormatsToTestBlit[]                   =
11434         {
11435                 { compatibleFormatsUInts,       true    },
11436                 { compatibleFormatsSInts,       true    },
11437                 { compatibleFormatsFloats,      false   },
11438                 { compatibleFormatsSrgb,        false   },
11439         };
11440
11441         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11442
11443         const int       layerCountsToTest[]                             =
11444         {
11445                 1,
11446                 6
11447         };
11448
11449         TestParams      params;
11450         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
11451         params.src.image.extent         = defaultExtent;
11452         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11453         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
11454         params.dst.image.extent         = defaultExtent;
11455         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11456         params.allocationKind           = allocationKind;
11457         params.extensionUse                     = extensionUse;
11458         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11459         params.singleCommand            = DE_FALSE;
11460
11461         CopyRegion      region;
11462         for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11463         {
11464                 VkImageSubresourceLayers        srcLayer        = defaultSourceLayer;
11465                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
11466
11467                 srcLayer.mipLevel       = mipLevelNdx - 1u;
11468                 destLayer.mipLevel      = mipLevelNdx;
11469
11470                 const VkImageBlit                       imageBlit       =
11471                 {
11472                         srcLayer,                       // VkImageSubresourceLayers     srcSubresource;
11473                         {
11474                                 {0, 0, 0},
11475                                 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
11476                         },                                      // VkOffset3D                                   srcOffsets[2];
11477
11478                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
11479                         {
11480                                 {0, 0, 0},
11481                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11482                         }                                       // VkOffset3D                                   dstOffset[2];
11483                 };
11484                 region.imageBlit        = imageBlit;
11485                 params.regions.push_back(region);
11486         }
11487
11488         if (allocationKind == ALLOCATION_KIND_DEDICATED)
11489         {
11490                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11491                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11492                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11493         }
11494
11495         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11496         {
11497                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
11498                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
11499                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11500
11501                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11502
11503                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11504                 {
11505                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11506                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11507
11508                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11509                         {
11510                                 params.src.image.format                                         = compatibleFormats[srcFormatIndex];
11511                                 params.dst.image.format                                         = compatibleFormats[srcFormatIndex];
11512
11513                                 if (!isSupportedByFramework(params.src.image.format))
11514                                         continue;
11515
11516                                 const bool                      onlyNearestAndLinear    = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11517
11518                                 const std::string       description                             = "Blit source format " + getFormatCaseName(params.src.image.format);
11519
11520                                 BlitColorTestParams     testParams;
11521                                 testParams.params                                                       = params;
11522                                 testParams.compatibleFormats                            = compatibleFormats;
11523                                 testParams.testFilters                                          = makeFilterMask(onlyNearest, onlyNearestAndLinear);
11524
11525                                 testParams.params.src.image.extent.depth        = layerCount;
11526                                 testParams.params.dst.image.extent.depth        = layerCount;
11527
11528                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11529                                 {
11530                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11531                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11532                                 }
11533
11534                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11535                         }
11536                 }
11537                 group->addChild(layerCountGroup.release());
11538         }
11539
11540         for (int multiLayer = 0; multiLayer < 2; multiLayer++)
11541         {
11542                 const int layerCount = multiLayer ? 6 : 1;
11543
11544                 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
11545                 {
11546                         if (layerCount != 1 || barrierCount != 1)
11547                         {
11548                                 const std::string                               barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
11549                                 const std::string                               barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
11550
11551                                 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
11552
11553                                 params.barrierCount = barrierCount;
11554
11555                                 // Only go through a few common formats
11556                                 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
11557                                 {
11558                                         params.src.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
11559                                         params.dst.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
11560
11561                                         if (!isSupportedByFramework(params.src.image.format))
11562                                                 continue;
11563
11564                                         const std::string description                           = "Blit source format " + getFormatCaseName(params.src.image.format);
11565
11566                                         BlitColorTestParams testParams;
11567                                         testParams.params                                                       = params;
11568                                         testParams.compatibleFormats                            = compatibleFormatsUInts;
11569                                         testParams.testFilters                                          = FILTER_MASK_NEAREST;
11570
11571                                         testParams.params.src.image.extent.depth        = layerCount;
11572                                         testParams.params.dst.image.extent.depth        = layerCount;
11573
11574                                         for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11575                                         {
11576                                                 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11577                                                 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11578                                         }
11579
11580                                         addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11581                                 }
11582                                 group->addChild(barrierCountGroup.release());
11583                         }
11584                 }
11585         }
11586 }
11587
11588 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11589 {
11590         addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
11591         addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
11592 }
11593
11594 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11595 {
11596         addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
11597         addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
11598         addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
11599 }
11600
11601 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11602 {
11603         addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
11604         addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
11605 }
11606
11607 const VkSampleCountFlagBits     samples[]               =
11608 {
11609         VK_SAMPLE_COUNT_2_BIT,
11610         VK_SAMPLE_COUNT_4_BIT,
11611         VK_SAMPLE_COUNT_8_BIT,
11612         VK_SAMPLE_COUNT_16_BIT,
11613         VK_SAMPLE_COUNT_32_BIT,
11614         VK_SAMPLE_COUNT_64_BIT
11615 };
11616 const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
11617
11618 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11619 {
11620         TestParams      params;
11621         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11622         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11623         params.src.image.extent                         = resolveExtent;
11624         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11625         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11626         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11627         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11628         params.dst.image.extent                         = resolveExtent;
11629         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11630         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11631         params.allocationKind                           = allocationKind;
11632         params.extensionUse                                     = extensionUse;
11633
11634         {
11635                 const VkImageSubresourceLayers  sourceLayer     =
11636                 {
11637                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11638                         0u,                                                     // deUint32                             mipLevel;
11639                         0u,                                                     // deUint32                             baseArrayLayer;
11640                         1u                                                      // deUint32                             layerCount;
11641                 };
11642                 const VkImageResolve                    testResolve     =
11643                 {
11644                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11645                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11646                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11647                         {0, 0, 0},              // VkOffset3D                           dstOffset;
11648                         resolveExtent,  // VkExtent3D                           extent;
11649                 };
11650
11651                 CopyRegion      imageResolve;
11652                 imageResolve.imageResolve       = testResolve;
11653                 params.regions.push_back(imageResolve);
11654         }
11655
11656         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11657         {
11658                 params.samples                                  = samples[samplesIndex];
11659                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11660                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11661         }
11662 }
11663
11664 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11665 {
11666         TestParams      params;
11667         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11668         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11669         params.src.image.extent                         = resolveExtent;
11670         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11671         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11672         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11673         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11674         params.dst.image.extent                         = resolveExtent;
11675         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11676         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11677         params.allocationKind                           = allocationKind;
11678         params.extensionUse                                     = extensionUse;
11679
11680         {
11681                 const VkImageSubresourceLayers  sourceLayer     =
11682                 {
11683                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11684                         0u,                                                     // deUint32                             mipLevel;
11685                         0u,                                                     // deUint32                             baseArrayLayer;
11686                         1u                                                      // deUint32                             layerCount;
11687                 };
11688                 const VkImageResolve                    testResolve     =
11689                 {
11690                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11691                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11692                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11693                         {64u, 64u, 0},          // VkOffset3D                           dstOffset;
11694                         {128u, 128u, 1u},       // VkExtent3D                           extent;
11695                 };
11696
11697                 CopyRegion      imageResolve;
11698                 imageResolve.imageResolve = testResolve;
11699                 params.regions.push_back(imageResolve);
11700         }
11701
11702         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11703         {
11704                 params.samples                                  = samples[samplesIndex];
11705                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11706                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11707         }
11708 }
11709
11710 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11711 {
11712         TestParams      params;
11713         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11714         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11715         params.src.image.extent                         = resolveExtent;
11716         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11717         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11718         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11719         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11720         params.dst.image.extent                         = resolveExtent;
11721         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11722         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11723         params.allocationKind                           = allocationKind;
11724         params.extensionUse                                     = extensionUse;
11725
11726         {
11727                 const VkImageSubresourceLayers  sourceLayer     =
11728                 {
11729                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11730                         0u,                                                     // deUint32                             mipLevel;
11731                         0u,                                                     // deUint32                             baseArrayLayer;
11732                         1u                                                      // deUint32                             layerCount;
11733                 };
11734
11735                 for (int i = 0; i < 256; i += 64)
11736                 {
11737                         const VkImageResolve                    testResolve     =
11738                         {
11739                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11740                                 {i, i, 0},              // VkOffset3D                           srcOffset;
11741                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11742                                 {i, 0, 0},              // VkOffset3D                           dstOffset;
11743                                 {64u, 64u, 1u}, // VkExtent3D                           extent;
11744                         };
11745
11746                         CopyRegion      imageResolve;
11747                         imageResolve.imageResolve = testResolve;
11748                         params.regions.push_back(imageResolve);
11749                 }
11750         }
11751
11752         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11753         {
11754                 params.samples                                  = samples[samplesIndex];
11755                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11756                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11757         }
11758 }
11759
11760 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11761 {
11762         TestParams      params;
11763         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11764         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11765         params.src.image.extent                         = defaultExtent;
11766         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11767         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11768         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11769         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11770         params.dst.image.extent                         = defaultExtent;
11771         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11772         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11773         params.allocationKind                           = allocationKind;
11774         params.extensionUse                                     = extensionUse;
11775
11776         {
11777                 const VkImageSubresourceLayers  sourceLayer     =
11778                 {
11779                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11780                         0u,                                                     // deUint32                             mipLevel;
11781                         0u,                                                     // deUint32                             baseArrayLayer;
11782                         1u                                                      // deUint32                             layerCount;
11783                 };
11784
11785                 const VkImageResolve                    testResolve     =
11786                 {
11787                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11788                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
11789                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11790                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
11791                         defaultExtent,          // VkExtent3D                           extent;
11792                 };
11793
11794                 CopyRegion      imageResolve;
11795                 imageResolve.imageResolve       = testResolve;
11796                 params.regions.push_back(imageResolve);
11797         }
11798
11799         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11800         {
11801                 params.samples                                  = samples[samplesIndex];
11802                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11803                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
11804         }
11805 }
11806
11807 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11808 {
11809         TestParams      params;
11810         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11811         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11812         params.src.image.extent                         = defaultExtent;
11813         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11814         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11815         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11816         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11817         params.dst.image.extent                         = defaultExtent;
11818         params.dst.image.extent.depth           = 5u;
11819         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11820         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11821         params.allocationKind                           = allocationKind;
11822         params.extensionUse                                     = extensionUse;
11823
11824         for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
11825         {
11826                 const VkImageSubresourceLayers  sourceLayer     =
11827                 {
11828                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
11829                         0u,                                                             // deUint32                             mipLevel;
11830                         layerNdx,                                               // deUint32                             baseArrayLayer;
11831                         1u                                                              // deUint32                             layerCount;
11832                 };
11833
11834                 const VkImageResolve                    testResolve     =
11835                 {
11836                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11837                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
11838                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11839                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
11840                         defaultExtent,          // VkExtent3D                           extent;
11841                 };
11842
11843                 CopyRegion      imageResolve;
11844                 imageResolve.imageResolve       = testResolve;
11845                 params.regions.push_back(imageResolve);
11846         }
11847
11848         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11849         {
11850                 params.samples                                  = samples[samplesIndex];
11851                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11852                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
11853         }
11854 }
11855
11856 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11857 {
11858         TestParams      params;
11859         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11860         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11861         params.src.image.extent                         = defaultExtent;
11862         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11863         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11864         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11865         params.dst.image.extent                         = defaultExtent;
11866         params.dst.image.extent.depth           = 5u;
11867         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11868         params.allocationKind                           = allocationKind;
11869         params.extensionUse                                     = extensionUse;
11870
11871         const VkImageSubresourceLayers  sourceLayer     =
11872         {
11873                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
11874                 0u,                                                             // uint32_t                             mipLevel;
11875                 0,                                              // uint32_t                             baseArrayLayer;
11876                 params.dst.image.extent.depth                   // uint32_t                             layerCount;
11877         };
11878
11879         const VkImageResolve                    testResolve     =
11880         {
11881                 sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11882                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
11883                 sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11884                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
11885                 defaultExtent,          // VkExtent3D                           extent;
11886         };
11887
11888         CopyRegion      imageResolve;
11889         imageResolve.imageResolve       = testResolve;
11890         params.regions.push_back(imageResolve);
11891
11892         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11893         {
11894                 params.samples                                  = samples[samplesIndex];
11895                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11896                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
11897         }
11898 }
11899
11900 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11901 {
11902         tcu::TestContext&       testCtx                 = group->getTestContext();
11903         TestParams                      params;
11904         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11905         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11906         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11907         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11908         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11909         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11910         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11911         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11912         params.allocationKind                           = allocationKind;
11913         params.extensionUse                                     = extensionUse;
11914
11915         {
11916                 const VkImageSubresourceLayers  sourceLayer     =
11917                 {
11918                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11919                         0u,                                                     // deUint32                             mipLevel;
11920                         0u,                                                     // deUint32                             baseArrayLayer;
11921                         1u                                                      // deUint32                             layerCount;
11922                 };
11923                 const VkImageResolve                    testResolve     =
11924                 {
11925                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11926                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11927                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11928                         {0, 0, 0},              // VkOffset3D                           dstOffset;
11929                         resolveExtent,  // VkExtent3D                           extent;
11930                 };
11931                 CopyRegion      imageResolve;
11932                 imageResolve.imageResolve       = testResolve;
11933                 params.regions.push_back(imageResolve);
11934         }
11935
11936         const VkExtent3D imageExtents[]         =
11937         {
11938                 { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
11939                 { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
11940                 { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
11941         };
11942
11943         for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
11944         {
11945                 const VkExtent3D&       srcImageSize    = imageExtents[srcImageExtentIndex];
11946                 params.src.image.extent                         = srcImageSize;
11947                 params.dst.image.extent                         = resolveExtent;
11948                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11949                 {
11950                         params.samples  = samples[samplesIndex];
11951                         std::ostringstream testName;
11952                         testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
11953                         std::ostringstream description;
11954                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
11955                                                 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
11956                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
11957                 }
11958         }
11959         for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
11960         {
11961                 const VkExtent3D&       dstImageSize    = imageExtents[dstImageExtentIndex];
11962                 params.src.image.extent                         = resolveExtent;
11963                 params.dst.image.extent                         = dstImageSize;
11964                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11965                 {
11966                         params.samples  = samples[samplesIndex];
11967                         std::ostringstream testName;
11968                         testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
11969                         std::ostringstream description;
11970                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
11971                                                 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
11972                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
11973                 }
11974         }
11975 }
11976
11977 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
11978 {
11979         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"));
11980
11981         for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
11982         for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
11983         {
11984                 BufferOffsetParams params{srcOffset, dstOffset};
11985                 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
11986         }
11987
11988         group->addChild(subGroup.release());
11989 }
11990
11991 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11992 {
11993         addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
11994         addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
11995         addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
11996         addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
11997         addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
11998         addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
11999         addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
12000 }
12001
12002 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12003 {
12004         addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
12005         addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
12006         addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
12007         addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
12008         addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
12009         addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
12010         addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
12011 }
12012
12013 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12014 {
12015         addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
12016         addBufferCopyOffsetTests(group);
12017 }
12018
12019
12020 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
12021 {
12022         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
12023 }
12024
12025 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12026 {
12027         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
12028 }
12029
12030 } // anonymous
12031
12032 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
12033 {
12034         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
12035
12036         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
12037         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",       "Copies And Blitting Tests For Dedicated Memory Allocation",    addDedicatedAllocationCopiesAndBlittingTests));
12038         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
12039
12040         return copiesAndBlittingTests.release();
12041 }
12042
12043 } // api
12044 } // vkt